From 5b540252f9636e5613ef1e8aba0af2cc5e08b373 Mon Sep 17 00:00:00 2001 From: Q Kim Date: Fri, 6 Oct 2023 10:40:01 +0900 Subject: [PATCH] =?UTF-8?q?refactor:=20=EB=B0=B0=ED=8F=AC=ED=95=9C=20`@piu?= =?UTF-8?q?m/stack-component`=20=EC=A0=81=EC=9A=A9=20(#419)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: update submodule * chore: pium stack component 설치 * refactor: 라이브러리 적용 * chore: 사용하지 않는 파일 삭제 * test: cypress 코드 수정 - dom 순서와 ui 순서가 같아져서 돌아가지 않던 코드 수정 --- backend/pium/src/main/resources/config | 2 +- frontend/cypress/e2e/petRegister.cy.ts | 14 +- frontend/env | 2 +- frontend/package-lock.json | 37 +++- frontend/package.json | 1 + .../@common/Stack/Stack.stories.tsx | 142 --------------- .../src/components/@common/Stack/index.tsx | 6 - .../@common/Stack/ingredients/Element.tsx | 27 --- .../@common/Stack/ingredients/Main.style.ts | 8 - .../@common/Stack/ingredients/Main.tsx | 15 -- .../petPlant/PetPlantRegisterForm/index.tsx | 167 ++++++++---------- frontend/src/hooks/@common/useStack.ts | 22 ++- 12 files changed, 128 insertions(+), 315 deletions(-) delete mode 100644 frontend/src/components/@common/Stack/Stack.stories.tsx delete mode 100644 frontend/src/components/@common/Stack/index.tsx delete mode 100644 frontend/src/components/@common/Stack/ingredients/Element.tsx delete mode 100644 frontend/src/components/@common/Stack/ingredients/Main.style.ts delete mode 100644 frontend/src/components/@common/Stack/ingredients/Main.tsx diff --git a/backend/pium/src/main/resources/config b/backend/pium/src/main/resources/config index 87718292d..6fec88683 160000 --- a/backend/pium/src/main/resources/config +++ b/backend/pium/src/main/resources/config @@ -1 +1 @@ -Subproject commit 87718292d0678843839f4e688720f6a22964bda5 +Subproject commit 6fec88683b39eaed5f0e644410f8e8a41cc2ff6f diff --git a/frontend/cypress/e2e/petRegister.cy.ts b/frontend/cypress/e2e/petRegister.cy.ts index e4f6abbde..a9c2836ec 100644 --- a/frontend/cypress/e2e/petRegister.cy.ts +++ b/frontend/cypress/e2e/petRegister.cy.ts @@ -71,36 +71,36 @@ describe('반려 식물 등록하기', () => { .get(`span[aria-label="${todayKorString}"]`) .click() - .get('input') - .last() + .get('input[type="text"]') + .first() .type('7') .get('button[aria-label="입력 완료"]') - .last() + .first() .click() .get('button[type="button"]') - .last() + .first() .click() .get('li[role="menuitem"]') .first() .click() .get('button[type="button"]') - .last() + .first() .click() .get('li[role="menuitem"]') .last() .click() .get('button[type="button"]') - .last() + .first() .click() .get('li[role="menuitem"]') .first() .click() .get('button[type="button"]') - .last() + .first() .click() .get('li[role="menuitem"]') .last() diff --git a/frontend/env b/frontend/env index 22eb37b3e..395ab4b2d 160000 --- a/frontend/env +++ b/frontend/env @@ -1 +1 @@ -Subproject commit 22eb37b3e470c40ff36c81dc3ce9f533a0bfe71d +Subproject commit 395ab4b2d029da4b23181f793fe2b2e8a6b29c37 diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 21a49634c..4f192ae67 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -1,14 +1,15 @@ { "name": "pium-frontend", - "version": "1.0.0", + "version": "1.1.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "pium-frontend", - "version": "1.0.0", + "version": "1.1.1", "license": "MIT", "dependencies": { + "@pium/stack-component": "^1.0.0", "@tanstack/react-query": "^5.0.0-beta.20", "react": "^18.2.0", "react-dom": "^18.2.0", @@ -3468,6 +3469,16 @@ "integrity": "sha512-Aq58f5HiWdyDlFffbbSjAlv596h/cOnt2DO1w3DOC7OJ5EHs0hd/nycJfiu9RJbT6Yk6F1knnRRXNSpxoIVZ9Q==", "dev": true }, + "node_modules/@pium/stack-component": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@pium/stack-component/-/stack-component-1.0.0.tgz", + "integrity": "sha512-MTjbf1YDQkjazg9BbmkC9iDb124DOKVnFHWMMOiwDPCWyV206ZcBY0plKKvBqC7e5Caqc9M9aWyMcn9woVRh6Q==", + "dependencies": { + "react": "^18.2.0", + "react-dom": "^18.2.0", + "styled-components": "^6.0.8" + } + }, "node_modules/@pmmmwh/react-refresh-webpack-plugin": { "version": "0.5.10", "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.10.tgz", @@ -19887,9 +19898,9 @@ "dev": true }, "node_modules/styled-components": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.0.2.tgz", - "integrity": "sha512-CRWTuYme0W4zVqzXpODByyocgVbBpRoXmaEgPGb67dvweV1igp7Ik4Z5C9e83wZ2l2hPg/XKV7cjuNxhRlC7Mg==", + "version": "6.0.8", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.0.8.tgz", + "integrity": "sha512-AwI02MTWZwqjzfXgR5QcbmcSn5xVjY4N2TLjSuYnmuBGF3y7GicHz3ysbpUq2EMJP5M8/Nc22vcmF3V3WNZDFA==", "dependencies": { "@babel/cli": "^7.21.0", "@babel/core": "^7.21.0", @@ -24446,6 +24457,16 @@ "integrity": "sha512-Aq58f5HiWdyDlFffbbSjAlv596h/cOnt2DO1w3DOC7OJ5EHs0hd/nycJfiu9RJbT6Yk6F1knnRRXNSpxoIVZ9Q==", "dev": true }, + "@pium/stack-component": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@pium/stack-component/-/stack-component-1.0.0.tgz", + "integrity": "sha512-MTjbf1YDQkjazg9BbmkC9iDb124DOKVnFHWMMOiwDPCWyV206ZcBY0plKKvBqC7e5Caqc9M9aWyMcn9woVRh6Q==", + "requires": { + "react": "^18.2.0", + "react-dom": "^18.2.0", + "styled-components": "^6.0.8" + } + }, "@pmmmwh/react-refresh-webpack-plugin": { "version": "0.5.10", "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.10.tgz", @@ -36629,9 +36650,9 @@ "dev": true }, "styled-components": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.0.2.tgz", - "integrity": "sha512-CRWTuYme0W4zVqzXpODByyocgVbBpRoXmaEgPGb67dvweV1igp7Ik4Z5C9e83wZ2l2hPg/XKV7cjuNxhRlC7Mg==", + "version": "6.0.8", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.0.8.tgz", + "integrity": "sha512-AwI02MTWZwqjzfXgR5QcbmcSn5xVjY4N2TLjSuYnmuBGF3y7GicHz3ysbpUq2EMJP5M8/Nc22vcmF3V3WNZDFA==", "requires": { "@babel/cli": "^7.21.0", "@babel/core": "^7.21.0", diff --git a/frontend/package.json b/frontend/package.json index 1283d9fa0..7f335a959 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -17,6 +17,7 @@ }, "license": "MIT", "dependencies": { + "@pium/stack-component": "^1.0.0", "@tanstack/react-query": "^5.0.0-beta.20", "react": "^18.2.0", "react-dom": "^18.2.0", diff --git a/frontend/src/components/@common/Stack/Stack.stories.tsx b/frontend/src/components/@common/Stack/Stack.stories.tsx deleted file mode 100644 index 9854d39c8..000000000 --- a/frontend/src/components/@common/Stack/Stack.stories.tsx +++ /dev/null @@ -1,142 +0,0 @@ -import type { Meta, StoryObj } from '@storybook/react'; -import { useState } from 'react'; -import Stack from '.'; -import useStack from '../../../hooks/@common/useStack'; - -const meta: Meta = { - component: Stack, -}; - -export default meta; - -type Story = StoryObj; - -const TestButton = ({ - type, - onClick, - isLastElementShown, -}: { - type: 'big' | 'small'; - onClick: () => void; - isLastElementShown: boolean; -}) => { - return ( - - ); -}; - -const Plain = () => { - const { topIndex, showNextElement, isLastElementShown } = useStack(6); - - const onClick = () => { - showNextElement(topIndex); - }; - - return ( - - - - - - - - - - - - - - - - - - - - - ); -}; - -/** - * Stack 안쪽 컴포넌트에서 useStackContext의 showNextElment를 호출하여 다음 스택 요소를 보여줍니다. - * - * 분홍색 버튼은 스토리북 확인을 위한 임시 컴포넌트이며, 실제 Stack에는 스타일이 존재하지 않습니다. - */ - -export const PlainExample: Story = { - render: Plain, -}; - -const Counter = ({ onClickNext }: { onClickNext: () => void }) => { - const [count, setCount] = useState(0); - - return ( -
-

{count}원 모았습니다.

-
- -
-
- -
-
- ); -}; - -const CounterStack = () => { - const { topIndex, showNextElement } = useStack(3); - - return ( - - - { - showNextElement(0); - }} - /> - - - { - showNextElement(1); - }} - /> - - - { - showNextElement(2); - }} - /> - - - ); -}; - -/** - * 역순으로 표시하지만 실제 DOM 순서를 꼬는 것이 아니기 때문에 버튼을 눌러 상태를 변경하더라도 상태는 변하지 않습니다. - */ - -export const StateExample: Story = { - render: CounterStack, -}; diff --git a/frontend/src/components/@common/Stack/index.tsx b/frontend/src/components/@common/Stack/index.tsx deleted file mode 100644 index 8673a64e8..000000000 --- a/frontend/src/components/@common/Stack/index.tsx +++ /dev/null @@ -1,6 +0,0 @@ -import Element from './ingredients/Element'; -import Main from './ingredients/Main'; - -const Stack = Object.assign(Main, { Element }); - -export default Stack; diff --git a/frontend/src/components/@common/Stack/ingredients/Element.tsx b/frontend/src/components/@common/Stack/ingredients/Element.tsx deleted file mode 100644 index 69fd5ef03..000000000 --- a/frontend/src/components/@common/Stack/ingredients/Element.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import styled, { keyframes } from 'styled-components'; - -const fall = (height: string) => keyframes` - from { - margin-top: -${height}; - transform: translateY(-${height}); - opacity: 0; - } - to { - margin-top: 0; - transform: translateY(0); - opacity: 1; - } -`; - -const Element = styled.div<{ height: string }>` - display: flex; - align-items: center; - - width: 100%; - height: ${({ height }) => height}; - margin-top: 0; - - animation: ${({ height }) => fall(height)} 0.4s linear; -`; - -export default Element; diff --git a/frontend/src/components/@common/Stack/ingredients/Main.style.ts b/frontend/src/components/@common/Stack/ingredients/Main.style.ts deleted file mode 100644 index 434eb331f..000000000 --- a/frontend/src/components/@common/Stack/ingredients/Main.style.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { styled } from 'styled-components'; - -export const Wrapper = styled.div` - display: flex; - flex-direction: column-reverse; - row-gap: 10px; - width: 100%; -`; diff --git a/frontend/src/components/@common/Stack/ingredients/Main.tsx b/frontend/src/components/@common/Stack/ingredients/Main.tsx deleted file mode 100644 index a1a82b5bb..000000000 --- a/frontend/src/components/@common/Stack/ingredients/Main.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { Wrapper } from './Main.style'; -import getFilteredChildren from 'utils/getFilteredChildren'; -import Element from './Element'; - -interface MainProps extends React.PropsWithChildren { - topIndex: number; -} - -const Main = ({ children, topIndex }: MainProps) => { - const elements = getFilteredChildren(, children); - - return {elements.slice(0, topIndex + 1)}; -}; - -export default Main; diff --git a/frontend/src/components/petPlant/PetPlantRegisterForm/index.tsx b/frontend/src/components/petPlant/PetPlantRegisterForm/index.tsx index 037767bde..3f102a2ce 100644 --- a/frontend/src/components/petPlant/PetPlantRegisterForm/index.tsx +++ b/frontend/src/components/petPlant/PetPlantRegisterForm/index.tsx @@ -1,3 +1,4 @@ +import { Stack } from '@pium/stack-component'; import DateInput from 'components/@common/DateInput'; import FormInput from 'components/@common/FormInput'; import FormInputBox from 'components/@common/FormInputBox'; @@ -5,7 +6,6 @@ import Image from 'components/@common/Image'; import ImageButton from 'components/@common/ImageButton'; import ProgressBar from 'components/@common/ProgressBar'; import Select from 'components/@common/Select'; -import Stack from 'components/@common/Stack'; import { AddImageButton, Button, @@ -29,7 +29,6 @@ interface PetPlantRegisterFormProps { } const STACK_SIZE = 9; -const STACK_ELEMENT_HEIGHT = '96px'; const PetPlantRegisterForm = (props: PetPlantRegisterFormProps) => { const { dictionaryPlantId, defaultNickname = '', dictionaryImageUrl } = props; @@ -37,7 +36,7 @@ const PetPlantRegisterForm = (props: PetPlantRegisterFormProps) => { ...initialPetPlantForm, nickname: defaultNickname, }); - const { topIndex, showNextElement } = useStack(STACK_SIZE); + const { showCount, showNextElement } = useStack(1, STACK_SIZE); const { uploadedImageUrl, fileUploadHandler, @@ -48,7 +47,7 @@ const PetPlantRegisterForm = (props: PetPlantRegisterFormProps) => { }); const today = getDateToString(); - const formProgressPercentage = Math.floor((topIndex / (STACK_SIZE - 1)) * 100); + const formProgressPercentage = Math.floor((showCount / STACK_SIZE) * 100); const isValidForm = Object.values(form).every((value) => value !== ''); const addToast = useAddToast(); @@ -59,7 +58,7 @@ const PetPlantRegisterForm = (props: PetPlantRegisterFormProps) => { }; const validateNickname = () => { - if (form.nickname !== '') showNextElement(0); + if (form.nickname.trim() !== '') showNextElement(0); }; const setBirthDate = (value: string) => { @@ -133,7 +132,7 @@ const PetPlantRegisterForm = (props: PetPlantRegisterFormProps) => { registerPetPlant({ imageData: imageBlob, requestForm }); }; - const getStatus = (index: number) => (topIndex === index ? 'focus' : 'default'); + const getInputBoxStatus = (index: number) => (showCount - 1 === index ? 'focus' : 'default'); return ( @@ -150,93 +149,75 @@ const PetPlantRegisterForm = (props: PetPlantRegisterFormProps) => {
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
-
+ + + + + + + + + + + + + + + + + + + +
+ +
); diff --git a/frontend/src/hooks/@common/useStack.ts b/frontend/src/hooks/@common/useStack.ts index 53ba48fbc..a5ae8cd53 100644 --- a/frontend/src/hooks/@common/useStack.ts +++ b/frontend/src/hooks/@common/useStack.ts @@ -1,17 +1,25 @@ import { useState } from 'react'; -const useStack = (stackSize: number) => { - const [topIndex, setTopIndex] = useState(0); - const isLastElementShown = topIndex + 1 === stackSize; +/** + * `@pium/stack-component`를 사용하기 위한 훅. + * @param initialShowCount 맨 처음에 보여줄 개수 + * @param stackSize 스택 안에 들어가는 요소의 수 + * @returns `showCount`: 현재 보여주는 개수 + * @returns `showNextElement`: 현재 보여지고 있는 마지막 요소의 index를 받았다면 다음 요소를 보여주는 함수 + * @returns `isLastElementShown`: 마지막 요소까지 전부 보여줬다면 `true` + */ +const useStack = (initialShowCount: number, stackSize: number) => { + const [showCount, setShowCount] = useState(initialShowCount); + const isLastElementShown = showCount === stackSize; - const showNextElement = (index: number) => { - const nextAlreadyShown = topIndex > index; + const showNextElement = (myIndex: number) => { + const nextAlreadyShown = showCount - 1 > myIndex; if (isLastElementShown || nextAlreadyShown) return; - setTopIndex(index + 1); + setShowCount(showCount + 1); }; - return { topIndex, showNextElement, isLastElementShown }; + return { showCount, showNextElement, isLastElementShown }; }; export default useStack;