From 07bd8f9d5099d935bae26a54df9838a84144d2a7 Mon Sep 17 00:00:00 2001 From: KIMSEI1124 Date: Sat, 9 Nov 2024 16:08:29 +0900 Subject: [PATCH 01/12] =?UTF-8?q?Feat(#38):=20Input=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EB=B0=8F=20=EC=8A=A4=ED=83=80=EC=9D=BC=20?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Common/Input/Input.styled.ts | 6 ++++++ src/components/Common/Input/Input.tsx | 19 +++++++++++++++++++ src/stories/Common/Input.stories.tsx | 17 +++++++++++++++++ 3 files changed, 42 insertions(+) create mode 100644 src/components/Common/Input/Input.styled.ts create mode 100644 src/components/Common/Input/Input.tsx create mode 100644 src/stories/Common/Input.stories.tsx diff --git a/src/components/Common/Input/Input.styled.ts b/src/components/Common/Input/Input.styled.ts new file mode 100644 index 0000000..da4cd6f --- /dev/null +++ b/src/components/Common/Input/Input.styled.ts @@ -0,0 +1,6 @@ +export interface InputStyling { + $width?: string; + $isValid?: boolean; + $void?: boolean; + $resize?: boolean; +} diff --git a/src/components/Common/Input/Input.tsx b/src/components/Common/Input/Input.tsx new file mode 100644 index 0000000..c4afc52 --- /dev/null +++ b/src/components/Common/Input/Input.tsx @@ -0,0 +1,19 @@ +import { ComponentPropsWithRef } from 'react'; + +import type { InputStyling } from './Input.styled'; + +export interface InputProps extends ComponentPropsWithRef<'input'> { + styles: InputStyling; +} + +function Input({ styles }: InputProps) { + const Tag = 'input'; + + return ( +
+ +
+ ); +} + +export default Input; diff --git a/src/stories/Common/Input.stories.tsx b/src/stories/Common/Input.stories.tsx new file mode 100644 index 0000000..63ed187 --- /dev/null +++ b/src/stories/Common/Input.stories.tsx @@ -0,0 +1,17 @@ +import type { Meta, StoryObj } from '@storybook/react'; + +import Input from '@/components/Common/Input/Input'; + +const meta: Meta = { + title: 'Common/Input', + component: Input, + tags: ['autodocs'], + args: { + styles: {}, + }, +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = {}; From 436935a92e39e214a9948dae10cde326369879e7 Mon Sep 17 00:00:00 2001 From: KIMSEI1124 Date: Sat, 9 Nov 2024 16:47:20 +0900 Subject: [PATCH 02/12] =?UTF-8?q?Feat(#38):=20Input=20=EA=B8=B0=EB=B3=B8?= =?UTF-8?q?=20=EC=8A=A4=ED=83=80=EC=9D=BC=20=EC=BD=94=EB=93=9C=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Common/Divider/Divider.styled.ts | 3 +- src/components/Common/Divider/Divider.tsx | 10 +--- src/components/Common/Input/Input.styled.ts | 49 +++++++++++++++++++ src/components/Common/Input/Input.tsx | 16 +++--- src/components/Common/InputText.ts | 8 +-- src/stories/Common/Input.stories.tsx | 11 ++++- 6 files changed, 76 insertions(+), 21 deletions(-) diff --git a/src/components/Common/Divider/Divider.styled.ts b/src/components/Common/Divider/Divider.styled.ts index b1934eb..432f3a1 100644 --- a/src/components/Common/Divider/Divider.styled.ts +++ b/src/components/Common/Divider/Divider.styled.ts @@ -1,10 +1,9 @@ -import { css } from '@emotion/css'; +import { css } from '@emotion/react'; export interface DividerStyling { $direction: 'vertical' | 'horizontal'; } -// FIXME: 해당 코드가 적용이 되지 않는 현상이 발생하여 추후 수정이 필요합니다. export const getDirectionStyling = ( direction: Required['$direction'], ) => { diff --git a/src/components/Common/Divider/Divider.tsx b/src/components/Common/Divider/Divider.tsx index c4162c6..0006af6 100644 --- a/src/components/Common/Divider/Divider.tsx +++ b/src/components/Common/Divider/Divider.tsx @@ -1,5 +1,6 @@ import { ComponentPropsWithRef, ElementType } from 'react'; +import { getDirectionStyling } from './Divider.styled'; import Flex from '../Flex/Flex'; import type { DividerStyling } from './Divider.styled'; @@ -31,14 +32,7 @@ function Divider({ tag = 'div', styles, text, ...attributes }: DividerProps) { css={{ inset: '0px' }} aria-hidden="true" > - + {text && ( ['$variant'], +) => { + const style = { + title: css({ + fontWeight: 'bold', + backgroundColor: 'transparent', + + '&:focus': { + borderColor: '#008080', + }, + }), + default: css({ + borderRadius: '0.375rem', + + '&:focus': { + outline: 'none', + boxShadow: '0 0 0 2px rgba(0, 128, 128, 0.5)', + }, + }), + }; + return style[variant]; +}; + +export const getInputStyling = () => { + return css({ + height: '2rem', + paddingLeft: '0.5rem', + paddingRight: '0.5rem', + transition: 'all 0.2s ease', + + '::placeholder': { + color: '#D1D5DB', + }, + + '&:hover': { + borderColor: '#9CA3AF', + }, + + '&:focus': { + outline: 'none', + }, + }); +}; diff --git a/src/components/Common/Input/Input.tsx b/src/components/Common/Input/Input.tsx index c4afc52..381a043 100644 --- a/src/components/Common/Input/Input.tsx +++ b/src/components/Common/Input/Input.tsx @@ -1,18 +1,20 @@ -import { ComponentPropsWithRef } from 'react'; +import type { ComponentPropsWithRef } from 'react'; + +import { getInputStyling, getVariantStyling } from './Input.styled'; import type { InputStyling } from './Input.styled'; export interface InputProps extends ComponentPropsWithRef<'input'> { + /** Input 스타일 옵션 */ styles: InputStyling; } -function Input({ styles }: InputProps) { - const Tag = 'input'; - +function Input({ styles, ...attributes }: InputProps) { return ( -
- -
+ ); } diff --git a/src/components/Common/InputText.ts b/src/components/Common/InputText.ts index 9f78737..1fc113d 100644 --- a/src/components/Common/InputText.ts +++ b/src/components/Common/InputText.ts @@ -11,13 +11,14 @@ type InputTextProps = { const InputDefault = styled.input` ${tw` h-8 - rounded-md px-2 transition placeholder:text-gray-300 hover:outline-gray-400 focus:!outline-none + + rounded-md focus:ring focus:ring-main `} @@ -32,14 +33,15 @@ const InputDefault = styled.input` const InputTitle = styled.input` ${tw` h-8 - bg-transparent - font-bold px-2 transition placeholder:text-gray-300 hover:border-gray-400 focus:!outline-none + + font-bold + bg-transparent focus:border-main `} ${(props) => (props.$void ? '' : tw`border-b-2`)} diff --git a/src/stories/Common/Input.stories.tsx b/src/stories/Common/Input.stories.tsx index 63ed187..b31ed46 100644 --- a/src/stories/Common/Input.stories.tsx +++ b/src/stories/Common/Input.stories.tsx @@ -7,7 +7,9 @@ const meta: Meta = { component: Input, tags: ['autodocs'], args: { - styles: {}, + styles: { + $variant: 'default', + }, }, }; @@ -15,3 +17,10 @@ export default meta; type Story = StoryObj; export const Default: Story = {}; +export const Title: Story = { + args: { + styles: { + $variant: 'title', + }, + }, +}; From 6e7d510636bef2451d6dab8cd9d2ea0a18eade93 Mon Sep 17 00:00:00 2001 From: KIMSEI1124 Date: Sun, 10 Nov 2024 18:52:04 +0900 Subject: [PATCH 03/12] =?UTF-8?q?Feat(#38):=20Input=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EB=84=8C=ED=8A=B8=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Common/Input/Input.styled.ts | 55 +++++++++++++++------ src/components/Common/Input/Input.tsx | 37 ++++++++++---- 2 files changed, 69 insertions(+), 23 deletions(-) diff --git a/src/components/Common/Input/Input.styled.ts b/src/components/Common/Input/Input.styled.ts index 1f57fac..382d394 100644 --- a/src/components/Common/Input/Input.styled.ts +++ b/src/components/Common/Input/Input.styled.ts @@ -1,51 +1,78 @@ import { css } from '@emotion/react'; -export interface InputStyling { - $variant: 'default' | 'title'; +import type { InputProps } from './Input'; - $width?: string; - $isValid?: boolean; - $void?: boolean; - $resize?: boolean; -} +import { Theme } from '@/styles/Theme.ts'; export const getVariantStyling = ( - variant: Required['$variant'], + variant: Required['$variant'], ) => { const style = { title: css({ fontWeight: 'bold', backgroundColor: 'transparent', - + border: 'none', + borderBottom: `2px solid ${Theme.color.black200}`, '&:focus': { - borderColor: '#008080', + borderColor: Theme.color.brown600, }, }), default: css({ borderRadius: '0.375rem', + border: `1px solid ${Theme.color.black200}`, '&:focus': { outline: 'none', - boxShadow: '0 0 0 2px rgba(0, 128, 128, 0.5)', + boxShadow: `0 0 0 2px ${Theme.color.brown600}`, }, }), }; return style[variant]; }; +export const getFlexStyling = (size: Required['$size']) => { + const style = { + small: css({ + margin: '6px 10px', + }), + medium: css({ + margin: '10px 14px', + }), + large: css({ + margin: '12px 16px', + }), + }; + return style[size]; +}; + +export const getSizeStyling = (size: Required['$size']) => { + const style = { + small: css({ + padding: '6px 10px', + }), + medium: css({ + padding: '8px 12px', + }), + large: css({ + padding: '12px 16px', + }), + }; + return style[size]; +}; + export const getInputStyling = () => { return css({ - height: '2rem', + width: '100%', paddingLeft: '0.5rem', paddingRight: '0.5rem', transition: 'all 0.2s ease', '::placeholder': { - color: '#D1D5DB', + color: Theme.color.black400, }, '&:hover': { - borderColor: '#9CA3AF', + borderColor: Theme.color.black200, }, '&:focus': { diff --git a/src/components/Common/Input/Input.tsx b/src/components/Common/Input/Input.tsx index 381a043..3c4dc84 100644 --- a/src/components/Common/Input/Input.tsx +++ b/src/components/Common/Input/Input.tsx @@ -1,20 +1,39 @@ import type { ComponentPropsWithRef } from 'react'; -import { getInputStyling, getVariantStyling } from './Input.styled'; +import { + getInputStyling, + getVariantStyling, + getSizeStyling, + getFlexStyling, +} from './Input.styled'; -import type { InputStyling } from './Input.styled'; +import Flex from '@/components/Common/Flex/Flex'; export interface InputProps extends ComponentPropsWithRef<'input'> { - /** Input 스타일 옵션 */ - styles: InputStyling; + /** Input 종류 */ + $variant?: 'default' | 'title'; + /** Input 크기 */ + $size?: 'small' | 'medium' | 'large'; + + $disable?: boolean; } -function Input({ styles, ...attributes }: InputProps) { +function Input({ + $variant = 'default', + $size = 'medium', + ...attributes +}: InputProps) { return ( - + + + ); } From 6c57ea89a1c51793d7451f65240ffe1d96b0862b Mon Sep 17 00:00:00 2001 From: KIMSEI1124 Date: Sun, 10 Nov 2024 20:48:10 +0900 Subject: [PATCH 04/12] =?UTF-8?q?Feat(#38):=20Input=20Story=20Book=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/stories/Common/Input.stories.tsx | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/stories/Common/Input.stories.tsx b/src/stories/Common/Input.stories.tsx index b31ed46..15b9fd1 100644 --- a/src/stories/Common/Input.stories.tsx +++ b/src/stories/Common/Input.stories.tsx @@ -7,9 +7,7 @@ const meta: Meta = { component: Input, tags: ['autodocs'], args: { - styles: { - $variant: 'default', - }, + $variant: 'default', }, }; @@ -19,8 +17,6 @@ type Story = StoryObj; export const Default: Story = {}; export const Title: Story = { args: { - styles: { - $variant: 'title', - }, + $variant: 'title', }, }; From 4333ce21c7695f5f86fa71f89a3e5c8592664c03 Mon Sep 17 00:00:00 2001 From: KIMSEI1124 Date: Sat, 30 Nov 2024 16:30:58 +0900 Subject: [PATCH 05/12] =?UTF-8?q?Feat(#38):=20=EC=9D=BC=EC=A0=95=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1=20=EB=AA=A8=EB=8B=AC=EC=B0=BD=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .eslintrc.cjs | 7 +- src/@types/Schedule.d.ts | 9 +- src/components/Common/Box/Box.styled.ts | 77 +++ src/components/Common/Box/Box.tsx | 33 + .../CalendarLabel/CalendarLabel.styled.ts | 61 ++ .../Common/CalendarLabel/CalendarLabel.tsx | 66 ++ src/components/Common/Center/Center.styled.ts | 12 + src/components/Common/Center/Center.tsx | 24 + src/components/Common/Input/Input.tsx | 2 - .../Common/LabelButton/LabelButton.styled.ts | 29 + .../Common/LabelButton/LabelButton.tsx | 51 ++ .../LabelListBox/LabelListBox.styled.ts | 0 .../Common/LabelListBox/LabelListBox.tsx | 101 +++ .../Common/ListBox/ListBox.styled.ts | 82 +++ src/components/Common/ListBox/ListBox.tsx | 116 ++++ .../Common/{ListBox.tsx => PrevListBox.tsx} | 35 +- .../Common/Textarea/Textarea.styled.ts | 34 + src/components/Common/Textarea/Textarea.tsx | 21 + src/components/Common/TimeInput/TimeInput.tsx | 21 + src/components/Common/Toggle/Toggle.tsx | 6 +- .../group/create/GroupCreatePanel.tsx | 6 +- .../group/update/GroupUpdatePanel.tsx | 6 +- src/components/label/CreateLabel.tsx | 4 +- .../navbar/sheet/member/MemberNickname.tsx | 9 +- src/components/review/write/REmotion.tsx | 14 +- src/components/review/write/RTitle.tsx | 6 +- src/components/review/write/RWeather.tsx | 18 +- src/components/schedule/ScheduleItems.tsx | 631 ++++++++---------- src/components/schedule/ScheduleModal.tsx | 4 +- src/components/schedule/SchedulePanel.tsx | 4 - src/components/widget/WGoal.tsx | 8 +- src/constants/Calendar.ts | 35 + src/stores/DateStore.ts | 2 + src/stories/Common/CalendarLabel.stories.tsx | 17 + src/stories/Common/LabelButton.stories.tsx | 17 + src/stories/Common/LabelListBox.stories.tsx | 46 ++ src/stories/Common/Listbox.stories.tsx | 23 + 37 files changed, 1229 insertions(+), 408 deletions(-) create mode 100644 src/components/Common/Box/Box.styled.ts create mode 100644 src/components/Common/Box/Box.tsx create mode 100644 src/components/Common/CalendarLabel/CalendarLabel.styled.ts create mode 100644 src/components/Common/CalendarLabel/CalendarLabel.tsx create mode 100644 src/components/Common/Center/Center.styled.ts create mode 100644 src/components/Common/Center/Center.tsx create mode 100644 src/components/Common/LabelButton/LabelButton.styled.ts create mode 100644 src/components/Common/LabelButton/LabelButton.tsx create mode 100644 src/components/Common/LabelListBox/LabelListBox.styled.ts create mode 100644 src/components/Common/LabelListBox/LabelListBox.tsx create mode 100644 src/components/Common/ListBox/ListBox.styled.ts create mode 100644 src/components/Common/ListBox/ListBox.tsx rename src/components/Common/{ListBox.tsx => PrevListBox.tsx} (61%) create mode 100644 src/components/Common/Textarea/Textarea.styled.ts create mode 100644 src/components/Common/Textarea/Textarea.tsx create mode 100644 src/components/Common/TimeInput/TimeInput.tsx create mode 100644 src/constants/Calendar.ts create mode 100644 src/stories/Common/CalendarLabel.stories.tsx create mode 100644 src/stories/Common/LabelButton.stories.tsx create mode 100644 src/stories/Common/LabelListBox.stories.tsx create mode 100644 src/stories/Common/Listbox.stories.tsx diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 2e3ca99..e2bca87 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -1,7 +1,12 @@ module.exports = { root: true, env: { browser: true, es2020: true }, - extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'plugin:react-hooks/recommended', 'plugin:storybook/recommended'], + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', + 'plugin:react-hooks/recommended', + 'plugin:storybook/recommended', + ], ignorePatterns: ['dist', '.eslintrc.cjs'], parser: '@typescript-eslint/parser', plugins: [ diff --git a/src/@types/Schedule.d.ts b/src/@types/Schedule.d.ts index 3915f77..54a0e58 100644 --- a/src/@types/Schedule.d.ts +++ b/src/@types/Schedule.d.ts @@ -1,6 +1,9 @@ +import { LabelColorType } from '@/styles/Theme'; + type RepetitionCycle = 'DAY' | 'WEEK' | 'MONTH' | 'YEAR'; type ScheduleCategory = 'MEMBER' | 'GROUP'; +// FIXME: Label 인터페이스로 수정하기 type Label = { category: string; id: number; @@ -14,7 +17,7 @@ type LabelResponse = { color: string; }; -interface MemberData { +export interface MemberData { member_id: number; nickname: string; profile_image: string; @@ -26,7 +29,7 @@ type GroupResponse = { title: string; // 그룹 이름 }; -interface ScheduleData { +export interface ScheduleData { scheduleId?: number; title: string; // 필수 description: string; // 선택 @@ -115,7 +118,7 @@ interface ScheduleDetailData { members: Member[]; //개인 일정일 경우 1명의 정보만 들어 } -interface RepeatData { +export interface RepeatData { repetitionCycle: string; // 필수 week: number; // week일 경우 몇 주에 한번 반복할지, 선택 dayOfWeek: number; // bit로 0100010와 같은 형태로, 선택 diff --git a/src/components/Common/Box/Box.styled.ts b/src/components/Common/Box/Box.styled.ts new file mode 100644 index 0000000..8738607 --- /dev/null +++ b/src/components/Common/Box/Box.styled.ts @@ -0,0 +1,77 @@ +import { css } from '@emotion/react'; + +import { Theme } from '@/styles/Theme'; + +export interface BoxStylingProps { + width?: string; + height?: string; + margin?: string; + marginRight?: string; + marginTop?: string; + marginLeft?: string; + marginBottom?: string; + padding?: string; + paddingTop?: string; + paddingRight?: string; + paddingBottom?: string; + paddingLeft?: string; + border?: string; + borderRadius?: string; + borderColor?: string; + borderTop?: string; + borderRight?: string; + borderBottom?: string; + borderLeft?: string; + backgroundColor?: string; + color?: string; + position?: 'static' | 'absolute' | 'relative' | 'fixed' | 'inherit'; +} + +export const getBoxStyling = ({ + width = '', + height = '', + margin = '', + marginRight = '', + marginTop = '', + marginLeft = '', + marginBottom = '', + padding = '', + paddingTop = '', + paddingRight = '', + paddingBottom = '', + paddingLeft = '', + border = '', + borderRadius = '', + borderColor = `${Theme.color.black200}`, + borderTop = '', + borderRight = '', + borderBottom = '', + borderLeft = '', + backgroundColor = '', + color = '', + position = 'static', +}: BoxStylingProps) => + css({ + width, + height, + margin, + marginRight, + marginTop, + marginLeft, + marginBottom, + padding, + paddingTop, + paddingRight, + paddingBottom, + paddingLeft, + border, + borderRadius, + borderColor, + borderTop, + borderRight, + borderBottom, + borderLeft, + backgroundColor, + color, + position, + }); diff --git a/src/components/Common/Box/Box.tsx b/src/components/Common/Box/Box.tsx new file mode 100644 index 0000000..e832dd3 --- /dev/null +++ b/src/components/Common/Box/Box.tsx @@ -0,0 +1,33 @@ +import type { ComponentPropsWithoutRef, ElementType } from 'react'; + +import type { BoxStylingProps } from '@/components/Common/Box/Box.styled.ts'; + +import { getBoxStyling } from '@/components/Common/Box/Box.styled.ts'; + +export interface BoxProps extends ComponentPropsWithoutRef<'div'> { + /** + * Box 컴포넌트가 사용할 HTML 태그 + * + * @default 'div' + */ + tag?: ElementType; + /** Box 컴포넌트 스타일 옵션 */ + styles?: BoxStylingProps; +} + +const Box = ({ + tag = 'div', + styles = {}, + children, + ...attributes +}: BoxProps) => { + const Tag = tag; + + return ( + + {children} + + ); +}; + +export default Box; diff --git a/src/components/Common/CalendarLabel/CalendarLabel.styled.ts b/src/components/Common/CalendarLabel/CalendarLabel.styled.ts new file mode 100644 index 0000000..9ab886b --- /dev/null +++ b/src/components/Common/CalendarLabel/CalendarLabel.styled.ts @@ -0,0 +1,61 @@ +import { css } from '@emotion/react'; + +import type { CalendarLabelProps } from './CalendarLabel'; + +import { LabelColorType, Theme } from '@/styles/Theme.ts'; + +export const getCalendarLabelStyling = () => { + return css({ + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + width: 'fit-content', + height: '2.25rem', + minWidth: '3.5rem', + padding: '0.25rem 0.75rem', + + borderWidth: '1px', + borderStyle: 'solid', + }); +}; + +export const getCalendarLabelVariantStyling = ( + variant: Required['$variant'], +) => { + const style = { + background: css({ + color: Theme.color.white, + }), + border: css({ + color: Theme.color.black, + + background: 'none', + }), + }; + + return style[variant]; +}; + +export const getCalendarLabelBorderStyling = ( + border: Required['$rounded'], +) => { + const style = { + small: css({ + borderRadius: Theme.borderRadius.small, + }), + medium: css({ + borderRadius: Theme.borderRadius.medium, + }), + large: css({ + borderRadius: Theme.borderRadius.large, + }), + }; + return style[border]; +}; + +export const getCalendarLabelColorStyling = (color: LabelColorType) => { + return css({ + borderColor: Theme.labelColor[color], + backgroundColor: Theme.labelColor[color], + }); +}; diff --git a/src/components/Common/CalendarLabel/CalendarLabel.tsx b/src/components/Common/CalendarLabel/CalendarLabel.tsx new file mode 100644 index 0000000..51b90d9 --- /dev/null +++ b/src/components/Common/CalendarLabel/CalendarLabel.tsx @@ -0,0 +1,66 @@ +import { ComponentPropsWithRef, ElementType } from 'react'; + +import { + getCalendarLabelBorderStyling, + getCalendarLabelColorStyling, + getCalendarLabelStyling, + getCalendarLabelVariantStyling, +} from './CalendarLabel.styled'; + +import { LabelColorType } from '@/styles/Theme'; + +export interface CalendarLabelProps extends ComponentPropsWithRef<'div'> { + /** + * 사용할 HTML 태그 유형을 지정합니다. + * + * @default: 'div' + */ + tag?: ElementType; + /** + * 라벨에 표시될 텍스트를 지정합니다. + */ + text: string; + /** + * 라벨의 모서리 스타일을 지정합니다. + * + * @default: 'medium' + */ + $rounded?: 'small' | 'medium' | 'large'; + /** + * 라벨의 스타일 변형을 지정합니다. + * + * @default: 'background' + */ + $variant?: 'background' | 'border'; + /** + * 라벨의 색상을 지정합니다. + */ + $color: LabelColorType; +} + +function CalendarLabel({ + tag = 'div', + $rounded = 'medium', + $variant = 'background', + $color, + text, + ...attributes +}: CalendarLabelProps) { + const Tag: ElementType = tag; + + return ( + + {text} + + ); +} + +export default CalendarLabel; diff --git a/src/components/Common/Center/Center.styled.ts b/src/components/Common/Center/Center.styled.ts new file mode 100644 index 0000000..ab9c857 --- /dev/null +++ b/src/components/Common/Center/Center.styled.ts @@ -0,0 +1,12 @@ +import { css } from '@emotion/react'; + +export const getCenterStyling = css({ + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + + width: '100%', + height: '100%', + + textAlign: 'center', +}); diff --git a/src/components/Common/Center/Center.tsx b/src/components/Common/Center/Center.tsx new file mode 100644 index 0000000..8e6586c --- /dev/null +++ b/src/components/Common/Center/Center.tsx @@ -0,0 +1,24 @@ +import type { ComponentPropsWithoutRef, ElementType } from 'react'; + +import { getCenterStyling } from '@/components/Common/Center/Center.styled'; + +export interface CenterProps extends ComponentPropsWithoutRef<'div'> { + /** + * Center 컴포넌트가 사용할 HTML 태그 + * + * @default 'div' + */ + tag?: ElementType; +} + +const Center = ({ tag = 'div', children, ...attributes }: CenterProps) => { + const Tag = tag; + + return ( + + {children} + + ); +}; + +export default Center; diff --git a/src/components/Common/Input/Input.tsx b/src/components/Common/Input/Input.tsx index 3c4dc84..4198bc4 100644 --- a/src/components/Common/Input/Input.tsx +++ b/src/components/Common/Input/Input.tsx @@ -14,8 +14,6 @@ export interface InputProps extends ComponentPropsWithRef<'input'> { $variant?: 'default' | 'title'; /** Input 크기 */ $size?: 'small' | 'medium' | 'large'; - - $disable?: boolean; } function Input({ diff --git a/src/components/Common/LabelButton/LabelButton.styled.ts b/src/components/Common/LabelButton/LabelButton.styled.ts new file mode 100644 index 0000000..d7fccbb --- /dev/null +++ b/src/components/Common/LabelButton/LabelButton.styled.ts @@ -0,0 +1,29 @@ +import { css } from '@emotion/react'; + +import { LabelColorType, Theme } from '@/styles/Theme.ts'; + +export const getLabelButtonColorStyling = ( + isSelected: boolean, + color: LabelColorType, +) => { + return css({ + display: 'flex', + alignItems: 'center', + justifyContent: 'center', + width: 'fit-content', + height: '2.25rem', // Tailwind's h-9 + minWidth: '3.5rem', // Tailwind's min-w-14 + padding: '0.25rem 0.75rem', // Tailwind's px-3 py-1 + borderRadius: '9999px', // Tailwind's rounded-full + + fontWeight: 600, // Tailwind's font-semibold + + color: Theme.color.white, + cursor: 'pointer', + + border: '1px solid', + + borderColor: !isSelected ? Theme.labelColor[color] : undefined, + backgroundColor: isSelected ? Theme.labelColor[color] : undefined, + }); +}; diff --git a/src/components/Common/LabelButton/LabelButton.tsx b/src/components/Common/LabelButton/LabelButton.tsx new file mode 100644 index 0000000..c556174 --- /dev/null +++ b/src/components/Common/LabelButton/LabelButton.tsx @@ -0,0 +1,51 @@ +import { ComponentPropsWithRef, ElementType } from 'react'; + +import { getLabelButtonColorStyling } from './LabelButton.styled'; + +import { LabelColorType } from '@/styles/Theme'; + +export interface LabelButtonProps extends ComponentPropsWithRef<'button'> { + /** + * LabelButton 컴포넌트가 사용할 HTML 태그 + * + * @default: 'button' + */ + tag?: ElementType; + /** + * 라벨에 표시될 텍스트를 지정합니다. + */ + text: string; + /** + * + * 버튼 색상이 있어야 하므로 기본값은 true입니다. + * + * @default: true + */ + $isSelected?: boolean; + /** + * + */ + $labelColor: LabelColorType; +} + +function LabelButton({ + tag = 'button', + text, + $labelColor = 'brown', + $isSelected = true, + ...attributes +}: LabelButtonProps) { + const Tag = tag; + + return ( + + {text} + + ); +} + +export default LabelButton; diff --git a/src/components/Common/LabelListBox/LabelListBox.styled.ts b/src/components/Common/LabelListBox/LabelListBox.styled.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/components/Common/LabelListBox/LabelListBox.tsx b/src/components/Common/LabelListBox/LabelListBox.tsx new file mode 100644 index 0000000..e02ffe9 --- /dev/null +++ b/src/components/Common/LabelListBox/LabelListBox.tsx @@ -0,0 +1,101 @@ +import { Fragment, SetStateAction, Dispatch } from 'react'; + +import { Listbox as HeadListBox, Transition } from '@headlessui/react'; + +import CalendarLabel from '../CalendarLabel/CalendarLabel'; +import { + getListBoxButtonStyling, + getListBoxOptionContainerStyling, + getListBoxSelectOptionStyling, + getListBoxSizeStyling, +} from '../ListBox/ListBox.styled'; + +import { LabelFilterData } from '@/@types/Schedule'; +import ChevronDown from '@/assets/icons/chevronDown.svg'; + +export type LabelListBoxType = LabelFilterData; + +export interface ListBoxProps { + /** 표시할 항목들의 배열 */ + list: Array; + /** 현재 선택된 항목의 상태 */ + selected: T; + /** 선택된 항목 상태를 변경하는 함수, 외부에서 상태 관리 가능 */ + setSelected: Dispatch>; + /** 리스트 상단에 추가할 컴포넌트 */ + topList?: React.ReactNode; + /** 리스트 하단에 추가할 컴포넌트 */ + bottomList?: React.ReactNode; + /** ListBox 크기 */ + $size?: 'small' | 'medium' | 'large'; +} + +function LabelListBox({ + list, + selected, + setSelected, + topList, + bottomList, + $size = 'medium', +}: ListBoxProps) { + const getMaxLength = (arr: Array): number => { + return arr + .map((item) => item.title) + .reduce((maxLength, str) => Math.max(maxLength, str.length), 0); + }; + + const width: number = 80 + getMaxLength(list) * 15; + return ( +
+ +
+ + {selected && ( + + )} + + + + + + + {topList &&
    {topList}
} + {list.map((item) => ( + + + + ))} + {bottomList &&
    {bottomList}
} +
+
+
+
+
+ ); +} + +export default LabelListBox; diff --git a/src/components/Common/ListBox/ListBox.styled.ts b/src/components/Common/ListBox/ListBox.styled.ts new file mode 100644 index 0000000..0684efe --- /dev/null +++ b/src/components/Common/ListBox/ListBox.styled.ts @@ -0,0 +1,82 @@ +import { css } from '@emotion/react'; + +import type { ListBoxProps } from './ListBox'; + +import { Theme } from '@/styles/Theme'; + +export const getListBoxSizeStyling = ( + size: Required['$size'], + width: number, +) => { + const style = { + small: css({ + width: `${width}px`, + height: '32px', + }), + medium: css({ + width: `${width}px`, + height: '40px', + }), + large: css({ + width: `${width}px`, + height: '48px', + }), + }; + + return style[size]; +}; + +export const getListBoxButtonStyling = () => { + return css({ + display: 'flex', + alignItems: 'center', + justifyContent: 'space-between', + + width: '100%', + height: '100%', + paddingRight: '0.5rem', + paddingLeft: '0.5rem', + + cursor: 'pointer', + + borderRadius: Theme.borderRadius.medium, + border: `1px solid ${Theme.color.black300}`, + + '&:hover': { + borderColor: Theme.color.black400, + }, + }); +}; + +export const getListBoxOptionContainerStyling = (width: number) => { + return css({ + position: 'relative', + zIndex: 20, + + width: `${width}px`, + marginTop: '0.25rem', + maxHeight: '15rem', + padding: '0px', + + listStyle: 'none', + borderRadius: Theme.borderRadius.small, + backgroundColor: Theme.color.white, + + boxShadow: `0px 10px 15px ${Theme.color.black200}, 0px 4px 6px ${Theme.color.black100}`, + }); +}; + +export const getListBoxSelectOptionStyling = () => { + return css({ + position: 'relative', + padding: '0.5rem', + borderRadius: Theme.borderRadius.small, + + cursor: 'pointer', + color: Theme.color.black900, + + '&:hover': { + backgroundColor: Theme.color.brown300, + }, + }); +}; diff --git a/src/components/Common/ListBox/ListBox.tsx b/src/components/Common/ListBox/ListBox.tsx new file mode 100644 index 0000000..bf402b9 --- /dev/null +++ b/src/components/Common/ListBox/ListBox.tsx @@ -0,0 +1,116 @@ +import { Fragment, SetStateAction, Dispatch } from 'react'; + +import { Listbox as HeadListBox, Transition } from '@headlessui/react'; + +import { + getListBoxButtonStyling, + getListBoxOptionContainerStyling, + getListBoxSelectOptionStyling, + getListBoxSizeStyling, +} from './ListBox.styled'; + +import ChevronDown from '@/assets/icons/chevronDown.svg'; + +export interface ListBoxProps { + /** 표시할 항목들의 배열 */ + list: Array; + /** 항목을 렌더링하는 함수, 각 항목을 JSX 요소로 변환하여 표시 */ + render?: (value: string) => JSX.Element; + /** 현재 선택된 항목의 상태 */ + selected: string; + /** 선택된 항목 상태를 변경하는 함수, 외부에서 상태 관리 가능 */ + setSelected: Dispatch>; + /** 리스트 상단에 추가할 컴포넌트 */ + topList?: React.ReactNode; + /** 리스트 하단에 추가할 컴포넌트 */ + bottomList?: React.ReactNode; + /** ListBox 크기 */ + $size?: 'small' | 'medium' | 'large'; + + margin?: string; // 추후 Margin 타입으로 지정하기 (검증 필요) +} + +function DefaultRender(value: string): JSX.Element { + return ( + + {value} + + ); +} + +function ListBox({ + list, + render = DefaultRender, + selected, + setSelected, + topList, + bottomList, + $size = 'medium', + margin, +}: ListBoxProps) { + const getMaxLength = (arr: Array): number => { + return arr + .map((item) => item.toString()) + .reduce((maxLength, str) => Math.max(maxLength, str.length), 0); + }; + + const width: number = 40 + getMaxLength(list) * 15; + + return ( +
+ +
+ + {render(selected)} + + + + + + + {topList &&
    {topList}
} + {list.map((item, index) => ( + + {render(item)} + + ))} + {bottomList &&
    {bottomList}
} +
+
+
+
+
+ ); +} + +export default ListBox; diff --git a/src/components/Common/ListBox.tsx b/src/components/Common/PrevListBox.tsx similarity index 61% rename from src/components/Common/ListBox.tsx rename to src/components/Common/PrevListBox.tsx index 4778147..7f41ef3 100644 --- a/src/components/Common/ListBox.tsx +++ b/src/components/Common/PrevListBox.tsx @@ -7,12 +7,12 @@ import ChevronDown from '@/assets/icons/chevronDown.svg'; type ListBoxProps = { list: Array; render?: (value: any) => JSX.Element | Array; - selected: any; // state - setSelected: Dispatch>; // state setter - width?: string; //tailwind class로 넣어 주세요 - height?: string; - topList?: React.ReactNode; // 리스트 상단에 추가할 컴포넌트 - bottomList?: React.ReactNode; // 리스트 하단에 추가할 컴포넌트 + selected: any; // 선택된 항목의 상태 + setSelected: Dispatch>; // 선택된 항목 상태를 변경하는 함수 + width?: string; // Tailwind 클래스명 (기본값: w-72) + height?: string; // Tailwind 클래스명 (기본값: h-8) + topList?: React.ReactNode; // 리스트 상단 추가 컴포넌트 + bottomList?: React.ReactNode; // 리스트 하단 추가 컴포넌트 }; function renderSpan(value: string | number): JSX.Element { @@ -30,11 +30,11 @@ function ListBox({ bottomList, }: ListBoxProps) { return ( -
+
{render(selected)} @@ -48,25 +48,23 @@ function ListBox({ leaveTo="opacity-0" > - {topList ? ( -
  • + {topList && ( +
      {topList} - - ) : null} - {list.map((item, itemIdx) => ( +
    + )} + {list.map((item, index) => ( - ` relative cursor-pointer select-none px-4 py-2 text-gray-700 ${ - active ? 'bg-main/20' : '' - }` + `relative cursor-pointer select-none px-4 py-2 text-gray-700 ${active ? 'bg-main/20' : ''}` } value={item} > {render(item)} ))} - {bottomList ?
  • {bottomList}
  • : null} + {bottomList &&
      {bottomList}
    }
    @@ -76,4 +74,3 @@ function ListBox({ } export default ListBox; -export { renderSpan }; diff --git a/src/components/Common/Textarea/Textarea.styled.ts b/src/components/Common/Textarea/Textarea.styled.ts new file mode 100644 index 0000000..e9a234c --- /dev/null +++ b/src/components/Common/Textarea/Textarea.styled.ts @@ -0,0 +1,34 @@ +import { css } from '@emotion/react'; + +import { Theme } from '@/styles/Theme.ts'; + +export const getTextareaResizeStyling = (canResize: boolean) => { + return css({ + resize: canResize ? 'both' : 'none', + }); +}; + +export const getTextareaStyling = () => { + return css({ + width: '100%', + paddingLeft: '0.5rem', + paddingRight: '0.5rem', + transition: 'all 0.2s ease', + + '::placeholder': { + color: Theme.color.black400, + }, + + '&:hover': { + borderColor: Theme.color.black200, + }, + + borderRadius: '0.375rem', + border: `1px solid ${Theme.color.black200}`, + + '&:focus': { + outline: 'none', + boxShadow: `0 0 0 2px ${Theme.color.brown600}`, + }, + }); +}; diff --git a/src/components/Common/Textarea/Textarea.tsx b/src/components/Common/Textarea/Textarea.tsx new file mode 100644 index 0000000..79a498a --- /dev/null +++ b/src/components/Common/Textarea/Textarea.tsx @@ -0,0 +1,21 @@ +import type { ComponentPropsWithoutRef } from 'react'; + +import { + getTextareaResizeStyling, + getTextareaStyling, +} from './Textarea.styled'; + +export interface TextareaProps extends ComponentPropsWithoutRef<'textarea'> { + $resize: boolean; +} + +function Textarea({ $resize, ...attributes }: TextareaProps) { + return ( + + ); +} + +export default Textarea; diff --git a/src/components/Common/TimeInput/TimeInput.tsx b/src/components/Common/TimeInput/TimeInput.tsx new file mode 100644 index 0000000..87727f8 --- /dev/null +++ b/src/components/Common/TimeInput/TimeInput.tsx @@ -0,0 +1,21 @@ +import { useState } from 'react'; + +export interface TimeInputProps {} + +export interface TimeDate { + meridiem: 'AM' | 'PM'; + hour: number; + minute: number; +} + +function TimeInput() { + const [data] = useState({ + meridiem: 'AM', + hour: 1, + minute: 0, + }); + + console.log(data); +} + +export default TimeInput; diff --git a/src/components/Common/Toggle/Toggle.tsx b/src/components/Common/Toggle/Toggle.tsx index d7d6992..4f06317 100644 --- a/src/components/Common/Toggle/Toggle.tsx +++ b/src/components/Common/Toggle/Toggle.tsx @@ -1,3 +1,5 @@ +import type { ComponentPropsWithRef } from 'react'; + import { Switch } from '@headlessui/react'; import { @@ -6,7 +8,7 @@ import { ToggleStyling, } from './Toggle.styled'; -export interface ToggleProps { +export interface ToggleProps extends ComponentPropsWithRef { /** 현재 활성화 상태를 나타냅니다. */ isEnabled: boolean; /** 활성화 상태를 변경하는 함수입니다. 현재 상태를 반전시켜 활성화 또는 비활성화합니다. */ @@ -23,12 +25,14 @@ function Toggle({ isEnabled, toggleHandler, styles = { $variant: 'primary' }, + ...attributes }: ToggleProps) { return ( diff --git a/src/components/group/create/GroupCreatePanel.tsx b/src/components/group/create/GroupCreatePanel.tsx index 9a54874..75d18d7 100644 --- a/src/components/group/create/GroupCreatePanel.tsx +++ b/src/components/group/create/GroupCreatePanel.tsx @@ -5,7 +5,7 @@ import { SearchMemberForCreateGroupData } from '@/@types/Member'; import { getMemberByEmail } from '@/api/member/getMemberbyEmail'; import noContent from '@/assets/lottie/noContent.json'; import ColorCircle from '@/components/Common/ColorCircle/ColorCircle'; -import { InputDefault } from '@/components/Common/InputText'; +import Input from '@/components/Common/Input/Input'; import PopOver from '@/components/Common/PopOver'; import * as S from '@/components/group/create/GroupCreatePanel.styled'; import PalettePanel from '@/components/PalettePanel/PalettePanel'; @@ -143,7 +143,7 @@ function GroupCreatePanel({ 그룹 이름 - 그룹 멤버 추가 - 10} value={searchMember} onChange={handleSearchMemberChange} diff --git a/src/components/group/update/GroupUpdatePanel.tsx b/src/components/group/update/GroupUpdatePanel.tsx index 4583ab1..e987468 100644 --- a/src/components/group/update/GroupUpdatePanel.tsx +++ b/src/components/group/update/GroupUpdatePanel.tsx @@ -5,7 +5,7 @@ import { SearchMemberForCreateGroupData } from '@/@types/Member'; import { getMemberByEmail } from '@/api/member/getMemberbyEmail'; import noContent from '@/assets/lottie/noContent.json'; import ColorCircle from '@/components/Common/ColorCircle/ColorCircle.tsx'; -import { InputDefault } from '@/components/Common/InputText'; +import Input from '@/components/Common/Input/Input'; import PopOver from '@/components/Common/PopOver'; import * as S from '@/components/group/create/GroupCreatePanel.styled'; import PalettePanel from '@/components/PalettePanel/PalettePanel'; @@ -141,7 +141,7 @@ function GroupUpdatePanel({ 그룹 이름 - 그룹 멤버 추가 - 10} value={searchMember} onChange={handleSearchMemberChange} diff --git a/src/components/label/CreateLabel.tsx b/src/components/label/CreateLabel.tsx index cf8b474..6486e6f 100644 --- a/src/components/label/CreateLabel.tsx +++ b/src/components/label/CreateLabel.tsx @@ -1,7 +1,7 @@ import { Dispatch, SetStateAction, useRef } from 'react'; import postCreateLabel from '@/api/label/postCreateLabel'; -import { InputDefault } from '@/components/Common/InputText'; +import Input from '@/components/Common/Input/Input'; import { CreateDiv } from '@/components/label/Styled'; import ColorSelectButton from '@/components/PalettePanel/ColorSelectButton/ColorSelectButton.tsx'; import useToastStore from '@/stores/ToastStore'; @@ -22,7 +22,7 @@ function CreateLabel({ color, setColor, handleKeyDown }: CreateLabelProps) { return ( - { diff --git a/src/components/navbar/sheet/member/MemberNickname.tsx b/src/components/navbar/sheet/member/MemberNickname.tsx index 9703220..b422385 100644 --- a/src/components/navbar/sheet/member/MemberNickname.tsx +++ b/src/components/navbar/sheet/member/MemberNickname.tsx @@ -4,9 +4,9 @@ import * as S from './MemberNickname.styled'; import { patchNickname } from '@/api/member/patchNickname'; import CheckIcon from '@/assets/icons/check.svg'; -import XIcon from '@/assets/icons/x.svg'; -import { InputDefault } from '@/components/Common/InputText'; -import useMemberStore from '@/stores/MemberStore'; +import XIcon from '@/assets/icons/x.svg'; +import Input from '@/components/Common/Input/Input'; +import useMemberStore from '@/stores/MemberStore'; function MemberNickname() { const { nickname, setNickname } = useMemberStore(); @@ -49,12 +49,11 @@ function MemberNickname() { {edit ? ( - diff --git a/src/components/review/write/REmotion.tsx b/src/components/review/write/REmotion.tsx index 0dbe6cc..abea41e 100644 --- a/src/components/review/write/REmotion.tsx +++ b/src/components/review/write/REmotion.tsx @@ -1,5 +1,3 @@ - - import Bad from '@/assets/icons/emoji/bad.svg'; import Congrats from '@/assets/icons/emoji/congrats.svg'; import Cry from '@/assets/icons/emoji/cry.svg'; @@ -11,11 +9,11 @@ import Sick from '@/assets/icons/emoji/sick.svg'; import Smile from '@/assets/icons/emoji/smile.svg'; import Stareyes from '@/assets/icons/emoji/stareyes.svg'; import Tired from '@/assets/icons/emoji/tired.svg'; -import Smiley from '@/assets/icons/smiley.svg'; +import Smiley from '@/assets/icons/smiley.svg'; import { WhiteContainer } from '@/components/Common/Container'; -import { InputDefault } from '@/components/Common/InputText'; +import Input from '@/components/Common/Input/Input'; import { EmotionContent } from '@/objects/ReviewContent.ts'; -import useReviewStore from '@/stores/ReviewStore'; +import useReviewStore from '@/stores/ReviewStore'; type REmotionProps = { index: number; @@ -108,9 +106,11 @@ function REmotion({ index, content }: REmotionProps) {
    {renderEmoji(content.emoji)} - handleTextInput(e.target.value)} /> diff --git a/src/components/review/write/RTitle.tsx b/src/components/review/write/RTitle.tsx index 9981efb..58a1ad8 100644 --- a/src/components/review/write/RTitle.tsx +++ b/src/components/review/write/RTitle.tsx @@ -1,5 +1,5 @@ import { WhiteContainer } from '@/components/Common/Container'; -import { InputTitle } from '@/components/Common/InputText'; +import Input from '@/components/Common/Input/Input'; type RTitleProps = { $title: string; @@ -9,9 +9,9 @@ type RTitleProps = { function RTitle({ $title, $setTitle }: RTitleProps) { return ( - { diff --git a/src/components/review/write/RWeather.tsx b/src/components/review/write/RWeather.tsx index 17b99b1..03347a0 100644 --- a/src/components/review/write/RWeather.tsx +++ b/src/components/review/write/RWeather.tsx @@ -4,11 +4,11 @@ import Cloud from '@/assets/icons/weather/cloud.svg'; import CloudAngledRain from '@/assets/icons/weather/cloudAngledRain.svg'; import CloudSnow from '@/assets/icons/weather/cloudSnow.svg'; import FastWind from '@/assets/icons/weather/fastWinds.svg'; -import Sun from '@/assets/icons/weather/sun.svg'; +import Sun from '@/assets/icons/weather/sun.svg'; import { WhiteContainer } from '@/components/Common/Container'; -import { InputDefault } from '@/components/Common/InputText'; +import Input from '@/components/Common/Input/Input'; import { WeatherContent } from '@/objects/ReviewContent.ts'; -import useReviewStore from '@/stores/ReviewStore'; +import useReviewStore from '@/stores/ReviewStore'; type RWeatherProps = { index: number; @@ -74,12 +74,20 @@ function RWeather({ index, content }: RWeatherProps) {
    {renderWeather(content.weather)} - handleTextInput(e.target.value)} /> + {/* handleTextInput(e.target.value)} + /> */}
    diff --git a/src/components/schedule/ScheduleItems.tsx b/src/components/schedule/ScheduleItems.tsx index 399cbba..6d3c2b1 100644 --- a/src/components/schedule/ScheduleItems.tsx +++ b/src/components/schedule/ScheduleItems.tsx @@ -1,27 +1,27 @@ -import React, { Dispatch, SetStateAction, useState } from 'react'; +import React, { Dispatch, SetStateAction } from 'react'; import * as S from './Schedule.styled'; -import { getLabelList } from '@/api/label/getLabelList'; +import type { Label, RepeatData, ScheduleData } from '@/@types/Schedule'; +import type { LabelColorType } from '@/styles/Theme'; + import ArrowRightIcon from '@/assets/icons/arrowRight.svg'; import CalendarAddIcon from '@/assets/icons/calendarAdd.svg'; import ClockIcon from '@/assets/icons/clock.svg'; -import Plus from '@/assets/icons/plus.svg'; import RepeatIcon from '@/assets/icons/repeat.svg'; import LabelIcon from '@/assets/icons/tag.svg'; import DescriptionIcon from '@/assets/icons/textAlignLeft.svg'; -import UsersIcon from '@/assets/icons/users.svg'; -import { - InputDefault, - InputTitle, - InputTextArea, -} from '@/components/Common/InputText'; +import Box from '@/components/Common/Box/Box'; +import Center from '@/components/Common/Center/Center'; +import Flex from '@/components/Common/Flex/Flex'; +import Input from '@/components/Common/Input/Input'; import LabelButton from '@/components/Common/LabelButton'; -import ListBox from '@/components/Common/ListBox'; +import ListBox from '@/components/Common/ListBox/ListBox'; +import PrevListBox from '@/components/Common/PrevListBox'; +import Textarea from '@/components/Common/Textarea/Textarea'; import Toggle from '@/components/Common/Toggle/Toggle'; -import CreateLabel from '@/components/label/CreateLabel'; +import { AM_PM, DAYS } from '@/constants/Calendar'; import useDateStore from '@/stores/DateStore'; -import { LabelColorType } from '@/styles/Theme'; type ChangeProps = { states: ScheduleData & RepeatData; @@ -39,41 +39,24 @@ type SetProps = { function Title({ states, handleChange }: ChangeProps) { return ( - + CalendarAdd - - +
    + +
    +
    ); } function Time({ states, handleChange, setStates }: ChangeProps & SetProps) { - const ampm = ['AM', 'PM']; - - // const onInputHour = (e: any) => { - // e.target.value = Math.floor(e.target.value); - // if (e.target.value < 1) { - // e.target.value = 1; - // } else if (e.target.value > 12) { - // e.target.value = 12; - // } - // }; - - // const onInputMinute = (e: any) => { - // e.target.value = Math.floor(e.target.value); - // if (e.target.value < 0) { - // e.target.value = 0; - // } else if (e.target.value > 59) { - // e.target.value = 59; - // } - // }; - const handleAllday = (value: boolean) => { setStates((prev) => { return { @@ -102,127 +85,129 @@ function Time({ states, handleChange, setStates }: ChangeProps & SetProps) { }; return ( - - Clock - - - 하루 종일 - >} + +
    + Clock +
    + + + > + } + css={{ marginLeft: '24px' }} + /> + 하루 종일 + + +
    +
    + + + -
    -
    -
    - - {states.isAllDay ? null : ( - - > - } - /> - - : - - - )} -
    arrow-right -
    - - {states.isAllDay ? null : ( - - > - } - /> - - : - - - )} -
    -
    -
    -
    + + + {/* TODO: 추후 Time Input 으로 리펙토링 예정 */} + {states.isAllDay === false && ( + + + > + } + /> + + : + + >} + /> + + : + + + + )} + + ); } function Description({ states, handleChange }: ChangeProps) { return ( - + Description - - + +