diff --git a/frontend/src/components/dashboard/ProcessColumn/ProcessDescription/ProcessDescription.stories.tsx b/frontend/src/components/dashboard/ProcessColumn/ProcessDescription/ProcessDescription.stories.tsx new file mode 100644 index 000000000..b2ec5678d --- /dev/null +++ b/frontend/src/components/dashboard/ProcessColumn/ProcessDescription/ProcessDescription.stories.tsx @@ -0,0 +1,35 @@ +import type { Meta, StoryObj } from '@storybook/react'; +import ProcessDescription from './index'; + +const meta: Meta = { + title: 'Components/ProcessColumn/ProcessDescription', + component: ProcessDescription, + parameters: { + layout: 'centered', + docs: { + description: { + component: '프로세스의 설명을 렌더링합니다. 더보기 버튼을 클릭하면 설명이 전체로 펼쳐집니다.', + }, + }, + }, + tags: ['autodocs'], + decorators: [ + (Child) => ( +
+ +
+ ), + ], + args: { + description: '프로세스 설명입니다.', + }, +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = {}; diff --git a/frontend/src/components/dashboard/ProcessColumn/ProcessDescription/index.tsx b/frontend/src/components/dashboard/ProcessColumn/ProcessDescription/index.tsx new file mode 100644 index 000000000..67c9edffd --- /dev/null +++ b/frontend/src/components/dashboard/ProcessColumn/ProcessDescription/index.tsx @@ -0,0 +1,32 @@ +import { useLayoutEffect, useRef, useState } from 'react'; +import S from './style'; + +interface ProcessDescriptionProps { + description: string; +} + +export default function ProcessDescription({ description }: ProcessDescriptionProps) { + const [isOverflow, setOverflow] = useState(false); + const [showMore, setShowMore] = useState(false); + + const toggleShowMore = () => setShowMore((prev) => !prev); + + const descriptionRef = useRef(null); + useLayoutEffect(() => { + if (descriptionRef.current) { + setOverflow(descriptionRef.current.scrollWidth > descriptionRef.current.clientWidth); + } + }, [description]); + + return ( + + + {description} + + {isOverflow && {showMore ? '접기' : '..더보기'}} + + ); +} diff --git a/frontend/src/components/dashboard/ProcessColumn/ProcessDescription/style.ts b/frontend/src/components/dashboard/ProcessColumn/ProcessDescription/style.ts new file mode 100644 index 000000000..881b4b54f --- /dev/null +++ b/frontend/src/components/dashboard/ProcessColumn/ProcessDescription/style.ts @@ -0,0 +1,48 @@ +import { css } from '@emotion/react'; +import styled from '@emotion/styled'; + +const Container = styled.div<{ showMore: boolean }>` + width: 100%; + display: flex; + align-items: baseline; + + ${({ showMore }) => + showMore && + css` + flex-direction: column; + align-items: flex-end; + `} +`; + +const Description = styled.p<{ showMore: boolean }>` + width: 100%; + + ${({ theme }) => theme.typography.common.block}; + color: ${({ theme }) => theme.baseColors.grayscale[700]}; + margin-bottom: 0; + padding: 0.4rem; + + ${({ showMore }) => + !showMore && + css` + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + `} +`; + +const MoreButton = styled.button` + ${({ theme }) => theme.typography.common.block}; + color: ${({ theme }) => theme.baseColors.grayscale[500]}; + + white-space: nowrap; + margin: 0; +`; + +const S = { + Container, + Description, + MoreButton, +}; + +export default S; diff --git a/frontend/src/components/dashboard/ProcessColumn/index.tsx b/frontend/src/components/dashboard/ProcessColumn/index.tsx index 3900943b9..ccb0ec30a 100644 --- a/frontend/src/components/dashboard/ProcessColumn/index.tsx +++ b/frontend/src/components/dashboard/ProcessColumn/index.tsx @@ -8,6 +8,7 @@ import { useModal } from '@contexts/ModalContext'; import S from './style'; import ApplicantCard from '../ApplicantCard'; +import ProcessDescription from './ProcessDescription/index'; interface ProcessColumnProps { process: Process; @@ -38,6 +39,7 @@ export default function ProcessColumn({ process }: ProcessColumnProps) { {process.name} + {process.applicants.map( diff --git a/frontend/src/components/dashboard/ProcessColumn/style.ts b/frontend/src/components/dashboard/ProcessColumn/style.ts index 39d2687ca..25a54eaba 100644 --- a/frontend/src/components/dashboard/ProcessColumn/style.ts +++ b/frontend/src/components/dashboard/ProcessColumn/style.ts @@ -7,9 +7,9 @@ const ProcessWrapper = styled.section` max-width: 25rem; height: 100%; - padding: 20px 12px 12px 12px; - border-radius: 8px; - border: 1px solid ${({ theme }) => theme.baseColors.grayscale[400]}; + padding: 1.2rem; + border-radius: 0.8rem; + border: 0.1rem solid ${({ theme }) => theme.baseColors.grayscale[400]}; background-color: ${({ theme }) => theme.baseColors.grayscale[50]}; overflow-y: scroll; @@ -19,16 +19,19 @@ const ProcessWrapper = styled.section` const Header = styled.header` display: flex; + flex-direction: column; + align-items: flex-start; justify-content: space-between; + gap: 0.8rem; - padding: 8px 4px; - margin-bottom: 20px; - border-bottom: 1px solid ${({ theme }) => theme.baseColors.grayscale[400]}; + padding: 0.8rem 0.4rem; + margin-bottom: 2rem; + border-bottom: 0.1rem solid ${({ theme }) => theme.baseColors.grayscale[400]}; `; const Title = styled.h2` ${({ theme }) => theme.typography.heading[500]}; - padding: 4px; + padding: 0.4rem; `; const ApplicantList = styled.ul` diff --git a/frontend/src/mocks/processMockData.json b/frontend/src/mocks/processMockData.json index a6ec7ac9c..e6273af61 100644 --- a/frontend/src/mocks/processMockData.json +++ b/frontend/src/mocks/processMockData.json @@ -43,7 +43,7 @@ } ], "name": "지원서", - "description": "지원서를 확인한다." + "description": "지원서를 확인한다.지원서를 확인한다.지원서를 확인한다.지원서를 확인한다.지원서를 확인한다.지원서를 확인한다.지원서를 확인한다." }, { "processId": 4,