diff --git a/src/features/diary-write/emotion/model/type.ts b/src/features/diary-write/emotion/model/type.ts new file mode 100644 index 0000000..1dea44b --- /dev/null +++ b/src/features/diary-write/emotion/model/type.ts @@ -0,0 +1,6 @@ +import { Emotions } from '@/shared/model/EmotionEnum'; + +export interface EmotionButtonGroupProps { + initialKeywords?: (Emotions | null)[]; + onKeywordsChange?: (keywords: (Emotions | null)[]) => void; +} diff --git a/src/features/diary-write/emotion/ui/EmotionButtonGroup.stories.ts b/src/features/diary-write/emotion/ui/EmotionButtonGroup.stories.ts new file mode 100644 index 0000000..98845ab --- /dev/null +++ b/src/features/diary-write/emotion/ui/EmotionButtonGroup.stories.ts @@ -0,0 +1,21 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import { EmotionButtonGroup } from './EmotionButtonGroup'; +import { Emotions } from '@/shared/model/EmotionEnum'; // Emotions 타입을 임포트 + +const meta: Meta = { + title: 'Features/DiaryWrite/EmotionButtonGroup', + component: EmotionButtonGroup, + tags: ['autodocs'] +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + initialKeywords: [null, null, null, null, null], + onKeywordsChange: (e) => { + console.log(e); + } + } +}; diff --git a/src/features/diary-write/emotion/ui/EmotionButtonGroup.styled.ts b/src/features/diary-write/emotion/ui/EmotionButtonGroup.styled.ts new file mode 100644 index 0000000..75af1f3 --- /dev/null +++ b/src/features/diary-write/emotion/ui/EmotionButtonGroup.styled.ts @@ -0,0 +1,48 @@ +import styled from 'styled-components'; + +export const EmotionButtonContainer = styled.div` + max-width: 960px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 30px; +`; + +export const Container = styled.div` + display: flex; + flex-direction: row; + flex-wrap: wrap; + align-items: center; + justify-content: space-between; + gap: 30px; +`; + +export const MainKeywordContainer = styled.div` + font-size: 14px; + font-family: 'Pretendard', sans-serif; + color: #8c8c8c; + display: flex; + flex-direction: column; + align-items: start; + gap: 0.5rem; +`; + +export const SubKeywordContainer = styled.div` + font-size: 14px; + font-family: 'Pretendard', sans-serif; + color: #8c8c8c; + display: flex; + flex-direction: column; + align-items: start; + gap: 0.5rem; +`; + +export const SubContainer = styled.div` + display: flex; + flex-direction: row; + flex-wrap: wrap; + align-items: center; + justify-content: start; + gap: 0.5rem; +`; diff --git a/src/features/diary-write/emotion/ui/EmotionButtonGroup.tsx b/src/features/diary-write/emotion/ui/EmotionButtonGroup.tsx new file mode 100644 index 0000000..008144e --- /dev/null +++ b/src/features/diary-write/emotion/ui/EmotionButtonGroup.tsx @@ -0,0 +1,84 @@ +import React, { useState } from 'react'; +import { EmotionButtonGroupProps } from '../model/type'; +import { + Container, + EmotionButtonContainer, + MainKeywordContainer, + SubKeywordContainer, + SubContainer +} from './EmotionButtonGroup.styled'; +import EmotionButtonList from '@/shared/EmotionButtonList/ui/EmotionButtonList'; +import { KeywordButton } from '@/entities/KeywordButton/ui/KeywordButton'; +import { Emotions } from '@/shared/model/EmotionEnum'; + +export const EmotionButtonGroup: React.FC = ({ + initialKeywords = [null, null, null, null, null], + onKeywordsChange +}) => { + const [keywords, setKeywords] = + useState<(Emotions | null)[]>(initialKeywords); + const [activeButton, setActiveButton] = useState(0); + + const handleClickKeyword = (index: number) => { + setActiveButton(index); + setKeywords((prevKeywords) => { + const newKeywords = [...prevKeywords]; + newKeywords[index] = null; + if (onKeywordsChange) { + onKeywordsChange(newKeywords); // 키워드 변화 이벤트 호출 + } + return newKeywords; + }); + }; + + const handleClickEmotion = (selectedEmotions: Emotions[]) => { + const newEmotion = selectedEmotions[0]; + + if (keywords[activeButton] !== newEmotion) { + setKeywords((prevKeywords) => { + const newKeywords = [...prevKeywords]; + newKeywords[activeButton] = newEmotion; + if (onKeywordsChange) { + onKeywordsChange(newKeywords); // 키워드 변화 이벤트 호출 + } + return newKeywords; + }); + + setActiveButton(activeButton !== 4 ? activeButton + 1 : 0); + } + }; + + return ( + + + + 대표 키워드 + handleClickKeyword(0)} + /> + + + 서브 키워드 + + {[1, 2, 3, 4].map((index) => ( + handleClickKeyword(index)} + /> + ))} + + + + + + ); +};