From d891a2a6e7b060bc92b3c25e6860478e8a282cc3 Mon Sep 17 00:00:00 2001 From: Yunseo Hwang Date: Fri, 31 Dec 2021 16:38:39 +0900 Subject: [PATCH 01/18] =?UTF-8?q?[#67]=20feat:=20IconTabNavbar=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/nav/IconTabNavbar/index.tsx | 113 +++++++++++++++ src/components/nav/IconTabNavbar/style.ts | 154 +++++++++++++++++++++ 2 files changed, 267 insertions(+) create mode 100644 src/components/nav/IconTabNavbar/index.tsx create mode 100644 src/components/nav/IconTabNavbar/style.ts diff --git a/src/components/nav/IconTabNavbar/index.tsx b/src/components/nav/IconTabNavbar/index.tsx new file mode 100644 index 0000000..d416a6d --- /dev/null +++ b/src/components/nav/IconTabNavbar/index.tsx @@ -0,0 +1,113 @@ +import { Theme } from '@emotion/react'; +import React, { FC, MouseEventHandler } from 'react'; +import { useHistory, useLocation } from 'react-router-dom'; + +import { + tabNavbarStyle, + tabIconStyle, + tabItemStyle, + tabCurvedBlockStyle, +} from './style'; + +type TabItemProps = { + to?: string; + onClickHandler?: MouseEventHandler; + children: React.ReactNode | ((selected: boolean) => React.ReactNode); +}; + +const TabItem: FC = ({ children, to, onClickHandler }) => { + const history = useHistory(); + const location = useLocation(); + + const onClickTabItem: MouseEventHandler = (e) => { + if (to) { + history.push(to); + } + if (onClickHandler) { + onClickHandler(e); + } + }; + + return ( + + ); +}; + +TabItem.defaultProps = { + to: null, + onClickHandler: null, +}; + +type TabIconProps = { + src: string; + children?: string; + to: string; + selectable?: boolean; +}; + +const TabIcon: FC = ({ children, src, to, selectable }) => { + return ( + + {(selected) => ( +
+
+
+ {children} +
+
+
+ )} + + ); +}; + +TabIcon.defaultProps = { + children: 'icon', + selectable: true, +}; + +type IconTabNavbarProps = { + direction?: 'top' | 'right' | 'bottom' | 'left'; +}; + +const IconTabNavbar: FC & { + TabIcon: FC; + TabItem: FC; +} = ({ children, direction }) => { + const isRow = direction === 'top' || direction === 'bottom'; + + return ( +
tabNavbarStyle(cssTheme, isRow)} + > + {children} +
+ ); +}; + +IconTabNavbar.defaultProps = { + direction: 'right', +}; + +IconTabNavbar.TabIcon = TabIcon; +IconTabNavbar.TabItem = TabItem; + +export default IconTabNavbar; diff --git a/src/components/nav/IconTabNavbar/style.ts b/src/components/nav/IconTabNavbar/style.ts new file mode 100644 index 0000000..e6b859a --- /dev/null +++ b/src/components/nav/IconTabNavbar/style.ts @@ -0,0 +1,154 @@ +import { SerializedStyles, Theme, css } from '@emotion/react'; + +export const tabCurvedBlockStyle = (theme: Theme): SerializedStyles => css` + display: flex; + + > .curved-block { + background-color: ${theme.colorPrimary}; + width: 20px; + height: 20px; + + ::after { + content: ''; + display: inline-block; + width: 100%; + height: 20px; + background-color: ${theme.colorWhite}; + } + } + + &.not-selected > .curved-block { + background-color: ${theme.colorWhite}; + } +`; + +export const tabItemStyle = css` + padding: 0; + border: none; + outline: none; + background-color: transparent; + position: relative; + text-align: center; +`; + +export const tabIconStyle = (theme: Theme): SerializedStyles => css` + display: inline-block; + padding: 10px; + + &.selected { + background-color: ${theme.colorPrimary}; + + img { + filter: brightness(0) invert(1); + } + } + + > img { + width: 35px; + height: 35px; + } +`; + +const curvedBlockStyleByDirection = css` + &.top { + align-items: flex-start; + } + &.left { + align-items: flex-start; + } + + &.top .curved-block-wrap, + &.bottom .curved-block-wrap { + flex-direction: row; + height: 100%; + } + + &.left .curved-block-wrap, + &.right .curved-block-wrap { + flex-direction: column; + } + + &.top .curved-block-wrap { + > .tab-icon { + border-radius: 0 0 50% 50%; + } + + > .curved-block { + &.start::after { + border-top-right-radius: 20px; + } + + &.end::after { + border-top-left-radius: 20px; + } + } + } + + &.right .curved-block-wrap { + align-items: flex-end; + + > .tab-icon { + border-radius: 50% 0 0 50%; + } + + > .curved-block { + &.start::after { + border-bottom-right-radius: 20px; + } + + &.end::after { + border-top-right-radius: 20px; + } + } + } + + &.bottom .curved-block-wrap { + align-items: flex-end; + + > .tab-icon { + border-radius: 50% 50% 0 0; + } + + > .curved-block { + &.start::after { + border-bottom-right-radius: 20px; + } + + &.end::after { + border-bottom-left-radius: 20px; + } + } + } + + &.left .curved-block-wrap { + > .tab-icon { + border-radius: 0 50% 50% 0; + } + + > .curved-block { + &.start::after { + border-bottom-left-radius: 20px; + } + + &.end::after { + border-top-left-radius: 20px; + } + } + } +`; + +export const tabNavbarStyle = ( + theme: Theme, + isRow: boolean, +): SerializedStyles => css` + position: relative; + display: flex; + overflow: hidden; + flex-direction: ${isRow ? 'row' : 'column'}; + + width: ${isRow ? '100%' : '70px'}; + height: ${isRow ? '70px' : '100%'}; + background-color: ${theme.colorWhite}; + + ${curvedBlockStyleByDirection} +`; From ddfa5467946682ebcb3569384bfca5072df8e59d Mon Sep 17 00:00:00 2001 From: Yunseo Hwang Date: Fri, 31 Dec 2021 16:39:55 +0900 Subject: [PATCH 02/18] =?UTF-8?q?[#67]=20chore:=20sidebar=EC=97=90=20?= =?UTF-8?q?=ED=95=84=EC=9A=94=ED=95=9C=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=EB=A6=AC=EC=86=8C=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/@types/image.d.ts | 1 + src/assets/images/chat-icon.svg | 3 +++ src/assets/images/setting-icon.svg | 3 +++ 3 files changed, 7 insertions(+) create mode 100644 src/assets/images/chat-icon.svg create mode 100644 src/assets/images/setting-icon.svg diff --git a/src/@types/image.d.ts b/src/@types/image.d.ts index 7c0da47..bb38b74 100644 --- a/src/@types/image.d.ts +++ b/src/@types/image.d.ts @@ -1,2 +1,3 @@ declare module '*.jpg'; declare module '*.png'; +declare module '*.svg'; diff --git a/src/assets/images/chat-icon.svg b/src/assets/images/chat-icon.svg new file mode 100644 index 0000000..8092d28 --- /dev/null +++ b/src/assets/images/chat-icon.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/images/setting-icon.svg b/src/assets/images/setting-icon.svg new file mode 100644 index 0000000..b103caa --- /dev/null +++ b/src/assets/images/setting-icon.svg @@ -0,0 +1,3 @@ + + + From 42582908d3ea891d384e49cf45a059757cc7a87a Mon Sep 17 00:00:00 2001 From: Yunseo Hwang Date: Sat, 1 Jan 2022 16:26:10 +0900 Subject: [PATCH 03/18] =?UTF-8?q?[#67]=20refactor:=20TabIcon=EC=97=90=20?= =?UTF-8?q?=EB=8C=80=ED=95=B4=20TabItem=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=20prop=EC=9D=84=20=EC=83=81=EC=86=8D=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/nav/IconTabNavbar/index.tsx | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/components/nav/IconTabNavbar/index.tsx b/src/components/nav/IconTabNavbar/index.tsx index d416a6d..e306f83 100644 --- a/src/components/nav/IconTabNavbar/index.tsx +++ b/src/components/nav/IconTabNavbar/index.tsx @@ -50,13 +50,18 @@ TabItem.defaultProps = { type TabIconProps = { src: string; children?: string; - to: string; selectable?: boolean; -}; +} & Omit; -const TabIcon: FC = ({ children, src, to, selectable }) => { +const TabIcon: FC = ({ + children, + src, + to, + selectable, + onClickHandler, +}) => { return ( - + {(selected) => (
Date: Sat, 1 Jan 2022 16:53:25 +0900 Subject: [PATCH 04/18] =?UTF-8?q?[#67]=20test:=20IconTabNavbar=EC=97=90=20?= =?UTF-8?q?=EB=8C=80=ED=95=9C=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../nav/IconTabNavbar/index.test.tsx | 139 ++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 src/components/nav/IconTabNavbar/index.test.tsx diff --git a/src/components/nav/IconTabNavbar/index.test.tsx b/src/components/nav/IconTabNavbar/index.test.tsx new file mode 100644 index 0000000..36e53a6 --- /dev/null +++ b/src/components/nav/IconTabNavbar/index.test.tsx @@ -0,0 +1,139 @@ +import React from 'react'; +import { MemoryRouter, Router } from 'react-router-dom'; +import { createMemoryHistory } from 'history'; + +import { render, screen, fireEvent } from '@testing-library/react'; + +import IconTabNavbar from '.'; + +describe(' component test', () => { + it('탭 요소들을 렌더링 해야 합니다.', () => { + render( + + + ITEM 1 + ITEM 2 + ITEM 3 + ICON 1 + ICON 2 + ICON 3 + + , + ); + + expect(screen.queryByText('ITEM 1')).toBeInTheDocument(); + expect(screen.queryByText('ITEM 2')).toBeInTheDocument(); + expect(screen.queryByText('ITEM 3')).toBeInTheDocument(); + + expect(screen.queryByAltText('ICON 1')).toBeInTheDocument(); + expect(screen.queryByAltText('ICON 2')).toBeInTheDocument(); + expect(screen.queryByAltText('ICON 3')).toBeInTheDocument(); + }); + + describe(' component test', () => { + it('자식 요소를 렌더링 해야 합니다.', () => { + render( + + Content + , + ); + + expect(screen.queryByText('Content')).toBeInTheDocument(); + }); + + it('함수로 전달된 자식 요소에 URL을 기반으로한 선택 여부를 전달해야 합니다.', () => { + render( + + + {(selected) => selected && 'TRUE'} + + , + ); + + expect(screen.queryByText('TRUE')).toBeInTheDocument(); + }); + + it('클릭 핸들러가 지정된 탭 요소를 클릭하면 해당 클릭 핸들러가 호출되어야 합니다.', () => { + let isClickHandlerCalled = false; + + render( + + { + isClickHandlerCalled = true; + }} + > + ITEM + + , + ); + + fireEvent.click(screen.getByText('ITEM')); + + expect(isClickHandlerCalled).toBeTruthy(); + }); + + it('링크 URL이 지정된 탭 요소를 클릭하면 해당 URL로 이동해야 합니다.', () => { + const history = createMemoryHistory(); + + render( + + ITEM + , + ); + + fireEvent.click(screen.getByText('ITEM')); + + expect(history.location.pathname).toBe('/target'); + }); + }); + + describe(' component test', () => { + const DEFAULT_ALT_TEXT = 'icon'; + + it('클릭 핸들러가 지정된 아이콘을 클릭하면 해당 클릭 핸들러가 호출되어야 합니다.', () => { + let isClickHandlerCalled = false; + + render( + + { + isClickHandlerCalled = true; + }} + /> + , + ); + + fireEvent.click(screen.getByRole('img', { name: DEFAULT_ALT_TEXT })); + + expect(isClickHandlerCalled).toBeTruthy(); + }); + + it('링크 URL이 지정된 아이콘을 클릭하면 해당 URL로 이동해야 합니다.', () => { + const history = createMemoryHistory(); + + render( + + + , + ); + + fireEvent.click(screen.getByRole('img', { name: DEFAULT_ALT_TEXT })); + + expect(history.location.pathname).toBe('/target'); + }); + + it('아이콘 이미지의 대체 텍스트를 지정할 수 있어야 합니다.', () => { + render( + + + Icon Alt Text + + , + ); + + expect(screen.queryByAltText('Icon Alt Text')).toBeInTheDocument(); + }); + }); +}); From 4d8f8284818c7f701ab476a619f8c27b751945ee Mon Sep 17 00:00:00 2001 From: Yunseo Hwang Date: Sat, 1 Jan 2022 17:58:34 +0900 Subject: [PATCH 05/18] =?UTF-8?q?[#67]=20refactor:=20IconTabNavbar=20?= =?UTF-8?q?=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=EC=9D=98=20display?= =?UTF-8?q?=EB=A5=BC=20inline-flex=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/nav/IconTabNavbar/style.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/nav/IconTabNavbar/style.ts b/src/components/nav/IconTabNavbar/style.ts index e6b859a..51e4634 100644 --- a/src/components/nav/IconTabNavbar/style.ts +++ b/src/components/nav/IconTabNavbar/style.ts @@ -142,7 +142,7 @@ export const tabNavbarStyle = ( isRow: boolean, ): SerializedStyles => css` position: relative; - display: flex; + display: inline-flex; overflow: hidden; flex-direction: ${isRow ? 'row' : 'column'}; From b9d22945be62cc4f4536011f96a248c076644cad Mon Sep 17 00:00:00 2001 From: Yunseo Hwang Date: Sat, 1 Jan 2022 19:38:40 +0900 Subject: [PATCH 06/18] =?UTF-8?q?[#67]=20refactor:=20IconTabNavbar?= =?UTF-8?q?=EB=A5=BC=20IconTabBar=EB=A1=9C=20=EB=84=A4=EC=9D=B4=EB=B0=8D?= =?UTF-8?q?=20=EB=B3=80=EA=B2=BD=20=EB=B0=8F=20common=20=EB=94=94=EB=A0=89?= =?UTF-8?q?=ED=86=A0=EB=A6=AC=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../IconTabBar}/index.test.tsx | 44 +++++++++---------- .../IconTabBar}/index.tsx | 16 +++---- .../IconTabBar}/style.ts | 2 +- 3 files changed, 31 insertions(+), 31 deletions(-) rename src/components/{nav/IconTabNavbar => common/IconTabBar}/index.test.tsx (74%) rename src/components/{nav/IconTabNavbar => common/IconTabBar}/index.tsx (88%) rename src/components/{nav/IconTabNavbar => common/IconTabBar}/style.ts (98%) diff --git a/src/components/nav/IconTabNavbar/index.test.tsx b/src/components/common/IconTabBar/index.test.tsx similarity index 74% rename from src/components/nav/IconTabNavbar/index.test.tsx rename to src/components/common/IconTabBar/index.test.tsx index 36e53a6..2f3765c 100644 --- a/src/components/nav/IconTabNavbar/index.test.tsx +++ b/src/components/common/IconTabBar/index.test.tsx @@ -4,20 +4,20 @@ import { createMemoryHistory } from 'history'; import { render, screen, fireEvent } from '@testing-library/react'; -import IconTabNavbar from '.'; +import IconTabBar from '.'; -describe(' component test', () => { +describe(' component test', () => { it('탭 요소들을 렌더링 해야 합니다.', () => { render( - - ITEM 1 - ITEM 2 - ITEM 3 - ICON 1 - ICON 2 - ICON 3 - + + ITEM 1 + ITEM 2 + ITEM 3 + ICON 1 + ICON 2 + ICON 3 + , ); @@ -30,11 +30,11 @@ describe(' component test', () => { expect(screen.queryByAltText('ICON 3')).toBeInTheDocument(); }); - describe(' component test', () => { + describe(' component test', () => { it('자식 요소를 렌더링 해야 합니다.', () => { render( - Content + Content , ); @@ -44,9 +44,9 @@ describe(' component test', () => { it('함수로 전달된 자식 요소에 URL을 기반으로한 선택 여부를 전달해야 합니다.', () => { render( - + {(selected) => selected && 'TRUE'} - + , ); @@ -58,13 +58,13 @@ describe(' component test', () => { render( - { isClickHandlerCalled = true; }} > ITEM - + , ); @@ -78,7 +78,7 @@ describe(' component test', () => { render( - ITEM + ITEM , ); @@ -88,7 +88,7 @@ describe(' component test', () => { }); }); - describe(' component test', () => { + describe(' component test', () => { const DEFAULT_ALT_TEXT = 'icon'; it('클릭 핸들러가 지정된 아이콘을 클릭하면 해당 클릭 핸들러가 호출되어야 합니다.', () => { @@ -96,7 +96,7 @@ describe(' component test', () => { render( - { isClickHandlerCalled = true; @@ -115,7 +115,7 @@ describe(' component test', () => { render( - + , ); @@ -127,9 +127,9 @@ describe(' component test', () => { it('아이콘 이미지의 대체 텍스트를 지정할 수 있어야 합니다.', () => { render( - + Icon Alt Text - + , ); diff --git a/src/components/nav/IconTabNavbar/index.tsx b/src/components/common/IconTabBar/index.tsx similarity index 88% rename from src/components/nav/IconTabNavbar/index.tsx rename to src/components/common/IconTabBar/index.tsx index e306f83..a7542cf 100644 --- a/src/components/nav/IconTabNavbar/index.tsx +++ b/src/components/common/IconTabBar/index.tsx @@ -3,7 +3,7 @@ import React, { FC, MouseEventHandler } from 'react'; import { useHistory, useLocation } from 'react-router-dom'; import { - tabNavbarStyle, + tabBarStyle, tabIconStyle, tabItemStyle, tabCurvedBlockStyle, @@ -88,11 +88,11 @@ TabIcon.defaultProps = { selectable: true, }; -type IconTabNavbarProps = { +type IconTabBarProps = { direction?: 'top' | 'right' | 'bottom' | 'left'; }; -const IconTabNavbar: FC & { +const IconTabBar: FC & { TabIcon: FC; TabItem: FC; } = ({ children, direction }) => { @@ -101,18 +101,18 @@ const IconTabNavbar: FC & { return (
tabNavbarStyle(cssTheme, isRow)} + css={(cssTheme: Theme) => tabBarStyle(cssTheme, isRow)} > {children}
); }; -IconTabNavbar.defaultProps = { +IconTabBar.defaultProps = { direction: 'right', }; -IconTabNavbar.TabIcon = TabIcon; -IconTabNavbar.TabItem = TabItem; +IconTabBar.TabIcon = TabIcon; +IconTabBar.TabItem = TabItem; -export default IconTabNavbar; +export default IconTabBar; diff --git a/src/components/nav/IconTabNavbar/style.ts b/src/components/common/IconTabBar/style.ts similarity index 98% rename from src/components/nav/IconTabNavbar/style.ts rename to src/components/common/IconTabBar/style.ts index 51e4634..7bc9032 100644 --- a/src/components/nav/IconTabNavbar/style.ts +++ b/src/components/common/IconTabBar/style.ts @@ -137,7 +137,7 @@ const curvedBlockStyleByDirection = css` } `; -export const tabNavbarStyle = ( +export const tabBarStyle = ( theme: Theme, isRow: boolean, ): SerializedStyles => css` From ca1d91520d9356c9f62548ab52e812eb7eb35584 Mon Sep 17 00:00:00 2001 From: Yunseo Hwang Date: Sat, 1 Jan 2022 20:21:04 +0900 Subject: [PATCH 07/18] =?UTF-8?q?[#67]=20feat:=20Sidebar=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/nav/Sidebar/index.test.tsx | 88 +++++++++++++++++++++++ src/components/nav/Sidebar/index.tsx | 45 ++++++++++++ src/components/nav/Sidebar/style.ts | 22 ++++++ src/constants/uri.ts | 1 + 4 files changed, 156 insertions(+) create mode 100644 src/components/nav/Sidebar/index.test.tsx create mode 100644 src/components/nav/Sidebar/index.tsx create mode 100644 src/components/nav/Sidebar/style.ts diff --git a/src/components/nav/Sidebar/index.test.tsx b/src/components/nav/Sidebar/index.test.tsx new file mode 100644 index 0000000..9a20b06 --- /dev/null +++ b/src/components/nav/Sidebar/index.test.tsx @@ -0,0 +1,88 @@ +import React from 'react'; +import { MemoryRouter, Router } from 'react-router-dom'; +import { createMemoryHistory } from 'history'; + +import { render, screen, fireEvent } from '@testing-library/react'; + +import Sidebar from '.'; + +describe(' component test', () => { + it('자식 요소들을 렌더링 해야 합니다.', () => { + render( + + Sidebar Contents + , + ); + + expect(screen.queryByText('Sidebar Contents')).toBeInTheDocument(); + }); + + it('Logo 아이콘을 클릭했을 때 home 페이지로 이동해야 합니다.', () => { + const history = createMemoryHistory(); + history.replace('/other'); + + render( + + + , + ); + + fireEvent.click(screen.getByAltText('Logo')); + + expect(history.location.pathname).toBe('/'); + }); + + it('Chat 아이콘을 클릭했을 때 feedback messages 페이지로 이동해야 합니다.', () => { + const history = createMemoryHistory(); + history.replace('/other'); + + render( + + + , + ); + + fireEvent.click(screen.getByAltText('Feedback Messages')); + + expect(history.location.pathname).toBe('/feedback'); + }); + + it('Setting 아이콘을 클릭했을 때 setting 페이지로 이동해야 합니다.', () => { + const history = createMemoryHistory(); + history.replace('/other'); + + render( + + + , + ); + + fireEvent.click(screen.getByAltText('Settings')); + + expect(history.location.pathname).toBe('/service-edit'); + }); + + it('해당 페이지로 이동했을 때 적절한 제목을 렌더링해야 합니다.', () => { + const DEFAULT_HEADING_TITLE = 'Telbby'; + + render( + + + , + ); + + expect(screen.queryByRole('heading')).toHaveTextContent( + DEFAULT_HEADING_TITLE, + ); + + fireEvent.click(screen.getByAltText('Feedback Messages')); + expect(screen.queryByRole('heading', { level: 1 })).toHaveTextContent( + 'Feedback Messages', + ); + + fireEvent.click(screen.getByAltText('Settings')); + expect(screen.queryByRole('heading', { level: 1 })).toHaveTextContent( + 'Settings', + ); + }); +}); diff --git a/src/components/nav/Sidebar/index.tsx b/src/components/nav/Sidebar/index.tsx new file mode 100644 index 0000000..c0271c0 --- /dev/null +++ b/src/components/nav/Sidebar/index.tsx @@ -0,0 +1,45 @@ +import React, { FC } from 'react'; + +import { useLocation } from 'react-router-dom'; +import IconTabBar from '@/components/common/IconTabBar'; +import Uri from '@/constants/uri'; + +import LogoIcon from '@/assets/images/logo.png'; +import ChatIcon from '@/assets/images/chat-icon.svg'; +import SettingIcon from '@/assets/images/setting-icon.svg'; + +import { sidebarContentStyle, sidebarStyle } from './style'; + +const SIDEBAR_HEADINGS = { + [Uri.feedback]: 'Feedback Messages', + [Uri.serviceEdit]: 'Settings', +}; + +const Sidebar: FC = ({ children }) => { + const location = useLocation(); + + return ( +
+ + + Logo + + + {SIDEBAR_HEADINGS[Uri.feedback]} + + + {SIDEBAR_HEADINGS[Uri.serviceEdit]} + + + +
+

+ {SIDEBAR_HEADINGS[location.pathname] ?? 'Telbby'} +

+ {children} +
+
+ ); +}; + +export default Sidebar; diff --git a/src/components/nav/Sidebar/style.ts b/src/components/nav/Sidebar/style.ts new file mode 100644 index 0000000..03d248e --- /dev/null +++ b/src/components/nav/Sidebar/style.ts @@ -0,0 +1,22 @@ +import { css, SerializedStyles, Theme } from '@emotion/react'; + +export const sidebarStyle = css` + display: inline-flex; + height: 100%; +`; + +export const sidebarContentStyle = (theme: Theme): SerializedStyles => css` + background-color: ${theme.colorPrimary}; + color: ${theme.colorWhite}; + width: 250px; + box-sizing: border-box; + padding: 12px 9px; + + > .title { + font-size: 50px; + font-family: ${theme.fontCodingBold}; + text-align: center; + + height: 160px; + } +`; diff --git a/src/constants/uri.ts b/src/constants/uri.ts index 7ac3115..1444ea2 100644 --- a/src/constants/uri.ts +++ b/src/constants/uri.ts @@ -4,6 +4,7 @@ enum Uri { signup = '/signup', service = '/service', serviceEdit = '/service-edit', + feedback = '/feedback', } export default Uri; From c303edd262aa8d9d76d48b09ed1b8a69002b52d2 Mon Sep 17 00:00:00 2001 From: Yunseo Hwang Date: Sat, 1 Jan 2022 20:38:39 +0900 Subject: [PATCH 08/18] =?UTF-8?q?[#67]=20refactor:=20Layout=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=EB=A5=BC=20layout=20=EB=94=94?= =?UTF-8?q?=EB=A0=89=ED=86=A0=EB=A6=AC=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/{common => layout}/Layout/index.test.tsx | 0 src/components/{common => layout}/Layout/index.tsx | 4 ++-- src/components/{common => layout}/Layout/style.ts | 0 src/pages/HomePage/index.tsx | 2 +- src/pages/NotFoundPage/index.tsx | 2 +- src/pages/ServiceEditPage/index.tsx | 2 +- src/pages/ServicePage/index.tsx | 2 +- 7 files changed, 6 insertions(+), 6 deletions(-) rename src/components/{common => layout}/Layout/index.test.tsx (100%) rename src/components/{common => layout}/Layout/index.tsx (72%) rename src/components/{common => layout}/Layout/style.ts (100%) diff --git a/src/components/common/Layout/index.test.tsx b/src/components/layout/Layout/index.test.tsx similarity index 100% rename from src/components/common/Layout/index.test.tsx rename to src/components/layout/Layout/index.test.tsx diff --git a/src/components/common/Layout/index.tsx b/src/components/layout/Layout/index.tsx similarity index 72% rename from src/components/common/Layout/index.tsx rename to src/components/layout/Layout/index.tsx index 8ed6929..32eba88 100644 --- a/src/components/common/Layout/index.tsx +++ b/src/components/layout/Layout/index.tsx @@ -1,7 +1,7 @@ import React, { FC } from 'react'; -import Navbar from '../Navbar'; -import Footer from '../Footer'; +import Navbar from '@/components/common/Navbar'; +import Footer from '@/components/common/Footer'; import { layoutStyle } from './style'; diff --git a/src/components/common/Layout/style.ts b/src/components/layout/Layout/style.ts similarity index 100% rename from src/components/common/Layout/style.ts rename to src/components/layout/Layout/style.ts diff --git a/src/pages/HomePage/index.tsx b/src/pages/HomePage/index.tsx index 142077e..ac3ae6e 100644 --- a/src/pages/HomePage/index.tsx +++ b/src/pages/HomePage/index.tsx @@ -1,6 +1,6 @@ import React, { FC } from 'react'; -import Layout from '@/components/common/Layout'; +import Layout from '@/components/layout/Layout'; import InduceSignup from '@/components/intro/InduceSignup'; import IntroMain from '@/components/intro/IntroMain'; import IntroWithClientUI from '@/components/intro/IntroWithClientUI'; diff --git a/src/pages/NotFoundPage/index.tsx b/src/pages/NotFoundPage/index.tsx index e21e9e0..37f065b 100644 --- a/src/pages/NotFoundPage/index.tsx +++ b/src/pages/NotFoundPage/index.tsx @@ -1,7 +1,7 @@ import React, { FC } from 'react'; import { Link } from 'react-router-dom'; -import Layout from '@/components/common/Layout'; +import Layout from '@/components/layout/Layout'; import Jumbotron from '@/components/common/Jumbotron'; import Uri from '@/constants/uri'; import notFoundImg from '@/assets/images/page-not-found.png'; diff --git a/src/pages/ServiceEditPage/index.tsx b/src/pages/ServiceEditPage/index.tsx index d63b624..d05d122 100644 --- a/src/pages/ServiceEditPage/index.tsx +++ b/src/pages/ServiceEditPage/index.tsx @@ -1,6 +1,6 @@ import React, { FC, useEffect, useState } from 'react'; -import Layout from '@/components/common/Layout'; +import Layout from '@/components/layout/Layout'; import ServiceEditForm from '@/components/service/ServiceEditForm'; import { ServiceInfo } from '@/types/service'; diff --git a/src/pages/ServicePage/index.tsx b/src/pages/ServicePage/index.tsx index 4b7abee..a1c86d4 100644 --- a/src/pages/ServicePage/index.tsx +++ b/src/pages/ServicePage/index.tsx @@ -1,7 +1,7 @@ import React, { FC } from 'react'; import Jumbotron from '@/components/common/Jumbotron'; -import Layout from '@/components/common/Layout'; +import Layout from '@/components/layout/Layout'; import ServiceList from '@/components/service/ServiceList'; import Shell from '@/components/shell/Shell'; From 10e29c1665c2977ce24ccd0ab403c0453bc9af3e Mon Sep 17 00:00:00 2001 From: Yunseo Hwang Date: Sat, 1 Jan 2022 21:12:12 +0900 Subject: [PATCH 09/18] =?UTF-8?q?[#67]=20refactor:=20Sidebar=20=EB=82=B4?= =?UTF-8?q?=EC=9A=A9=EB=AC=BC=EC=9D=98=20height=EB=A5=BC=20100%=EB=A1=9C?= =?UTF-8?q?=20=EB=A7=8C=EB=93=A4=EC=96=B4=EC=A3=BC=EA=B8=B0=20=EC=9C=84?= =?UTF-8?q?=ED=95=9C=20=EC=8A=A4=ED=83=80=EC=9D=BC=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/nav/Sidebar/index.tsx | 4 ++-- src/components/nav/Sidebar/style.ts | 8 +++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/components/nav/Sidebar/index.tsx b/src/components/nav/Sidebar/index.tsx index c0271c0..c95a33a 100644 --- a/src/components/nav/Sidebar/index.tsx +++ b/src/components/nav/Sidebar/index.tsx @@ -33,10 +33,10 @@ const Sidebar: FC = ({ children }) => {
-

+

{SIDEBAR_HEADINGS[location.pathname] ?? 'Telbby'}

- {children} +
{children}
); diff --git a/src/components/nav/Sidebar/style.ts b/src/components/nav/Sidebar/style.ts index 03d248e..60b3a82 100644 --- a/src/components/nav/Sidebar/style.ts +++ b/src/components/nav/Sidebar/style.ts @@ -11,12 +11,18 @@ export const sidebarContentStyle = (theme: Theme): SerializedStyles => css` width: 250px; box-sizing: border-box; padding: 12px 9px; + display: flex; + flex-direction: column; - > .title { + > .head { font-size: 50px; font-family: ${theme.fontCodingBold}; text-align: center; height: 160px; } + + > .body { + height: 100%; + } `; From 4d2d607e69cd604272381dc0f8bb8291204cb7c8 Mon Sep 17 00:00:00 2001 From: Yunseo Hwang Date: Sat, 1 Jan 2022 21:37:06 +0900 Subject: [PATCH 10/18] =?UTF-8?q?[#67]=20refactor:=20=EC=82=AC=EC=9D=B4?= =?UTF-8?q?=EB=93=9C=EB=B0=94=EC=97=90=EC=84=9C=20=EB=A1=9C=EA=B3=A0=20?= =?UTF-8?q?=ED=81=B4=EB=A6=AD=20=EC=8B=9C=20=EC=84=9C=EB=B9=84=EC=8A=A4=20?= =?UTF-8?q?=EB=A6=AC=EC=8A=A4=ED=8A=B8=20=ED=8E=98=EC=9D=B4=EC=A7=80?= =?UTF-8?q?=EB=A1=9C=20=EC=9D=B4=EB=8F=99=ED=95=98=EB=8F=84=EB=A1=9D=20URL?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/nav/Sidebar/index.test.tsx | 4 ++-- src/components/nav/Sidebar/index.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/nav/Sidebar/index.test.tsx b/src/components/nav/Sidebar/index.test.tsx index 9a20b06..cdd6088 100644 --- a/src/components/nav/Sidebar/index.test.tsx +++ b/src/components/nav/Sidebar/index.test.tsx @@ -17,7 +17,7 @@ describe(' component test', () => { expect(screen.queryByText('Sidebar Contents')).toBeInTheDocument(); }); - it('Logo 아이콘을 클릭했을 때 home 페이지로 이동해야 합니다.', () => { + it('Logo 아이콘을 클릭했을 때 service 페이지로 이동해야 합니다.', () => { const history = createMemoryHistory(); history.replace('/other'); @@ -29,7 +29,7 @@ describe(' component test', () => { fireEvent.click(screen.getByAltText('Logo')); - expect(history.location.pathname).toBe('/'); + expect(history.location.pathname).toBe('/service'); }); it('Chat 아이콘을 클릭했을 때 feedback messages 페이지로 이동해야 합니다.', () => { diff --git a/src/components/nav/Sidebar/index.tsx b/src/components/nav/Sidebar/index.tsx index c95a33a..0a2de3b 100644 --- a/src/components/nav/Sidebar/index.tsx +++ b/src/components/nav/Sidebar/index.tsx @@ -21,7 +21,7 @@ const Sidebar: FC = ({ children }) => { return (
- + Logo From 0a8d097c0fd914b72cef94b2ddf4065cc963b30f Mon Sep 17 00:00:00 2001 From: Yunseo Hwang Date: Sat, 1 Jan 2022 21:41:16 +0900 Subject: [PATCH 11/18] =?UTF-8?q?[#67]=20feat:=20SideLayout=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../layout/SideLayout/index.test.tsx | 74 +++++++++++++++++++ src/components/layout/SideLayout/index.tsx | 42 +++++++++++ src/components/layout/SideLayout/style.ts | 32 ++++++++ 3 files changed, 148 insertions(+) create mode 100644 src/components/layout/SideLayout/index.test.tsx create mode 100644 src/components/layout/SideLayout/index.tsx create mode 100644 src/components/layout/SideLayout/style.ts diff --git a/src/components/layout/SideLayout/index.test.tsx b/src/components/layout/SideLayout/index.test.tsx new file mode 100644 index 0000000..9b920d3 --- /dev/null +++ b/src/components/layout/SideLayout/index.test.tsx @@ -0,0 +1,74 @@ +import React from 'react'; +import { MemoryRouter, Router } from 'react-router-dom'; + +import { fireEvent, render, screen } from '@testing-library/react'; + +import { createMemoryHistory } from 'history'; +import SideLayout from '.'; + +describe(' component test', () => { + it('자식 요소들을 main 태그 밑에 렌더링 해야 합니다.', () => { + render( + + Main Contents + , + ); + expect(screen.getByRole('main')).toHaveTextContent('Main Contents'); + }); + + it('render prop으로 받은 요소를 사이드바 밑에 렌더링해야 합니다.', () => { + render( + +
Sidebar Contents
}> + Main Contents +
+
, + ); + expect(screen.queryByText('Sidebar Contents')).toBeInTheDocument(); + }); + + it('Logo 아이콘을 클릭했을 때 service 페이지로 이동해야 합니다.', () => { + const history = createMemoryHistory(); + history.replace('/other'); + + render( + + Main Contents + , + ); + + fireEvent.click(screen.getByAltText('Logo')); + + expect(history.location.pathname).toBe('/service'); + }); + + it('Chat 아이콘을 클릭했을 때 feedback messages 페이지로 이동해야 합니다.', () => { + const history = createMemoryHistory(); + history.replace('/other'); + + render( + + Main Contents + , + ); + + fireEvent.click(screen.getByAltText('Feedback Messages')); + + expect(history.location.pathname).toBe('/feedback'); + }); + + it('Setting 아이콘을 클릭했을 때 setting 페이지로 이동해야 합니다.', () => { + const history = createMemoryHistory(); + history.replace('/other'); + + render( + + Main Contents + , + ); + + fireEvent.click(screen.getByAltText('Settings')); + + expect(history.location.pathname).toBe('/service-edit'); + }); +}); diff --git a/src/components/layout/SideLayout/index.tsx b/src/components/layout/SideLayout/index.tsx new file mode 100644 index 0000000..3e72c94 --- /dev/null +++ b/src/components/layout/SideLayout/index.tsx @@ -0,0 +1,42 @@ +import React, { FC } from 'react'; + +import Footer from '@/components/common/Footer'; +import Sidebar from '@/components/nav/Sidebar'; + +import { + sideLayoutContentStyle, + sideLayoutStyle, + sidebarContentStyle, +} from './style'; + +type SideLayoutProps = { + children: React.ReactNode; + renderSidebar?: () => React.ReactNode; +}; + +const SideLayout: FC = ({ children, renderSidebar }) => { + return ( +
+ +
+
{renderSidebar && renderSidebar()}
+
+ {/* @TODO 요 위치에 서비스 리스트 Dropdown을 렌더링해줘야 합니다. */} + Telbby +
+
+
+ +
+
{children}
+
+
+
+ ); +}; + +SideLayout.defaultProps = { + renderSidebar: null, +}; + +export default SideLayout; diff --git a/src/components/layout/SideLayout/style.ts b/src/components/layout/SideLayout/style.ts new file mode 100644 index 0000000..fb856bf --- /dev/null +++ b/src/components/layout/SideLayout/style.ts @@ -0,0 +1,32 @@ +import { SerializedStyles, Theme, css } from '@emotion/react'; + +export const sideLayoutStyle = (theme: Theme): SerializedStyles => css` + width: 100%; + height: 100%; + display: flex; + background-color: ${theme.colorBg}; +`; + +export const sideLayoutContentStyle = css` + width: 100%; + height: 100%; + overflow: auto; + display: flex; + flex-direction: column; + + footer { + margin-top: auto; + } +`; + +export const sidebarContentStyle = css` + display: flex; + flex-direction: column; + padding: 10px 12px; + height: 100%; + box-sizing: border-box; + + > .footer { + margin-top: auto; + } +`; From d5ce487af44d132cab65711b505fc9b3e6c4104b Mon Sep 17 00:00:00 2001 From: Yunseo Hwang Date: Sat, 1 Jan 2022 21:48:36 +0900 Subject: [PATCH 12/18] =?UTF-8?q?[#67]=20feat:=20FeedbackMessagePage=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/App.tsx | 14 +++++++++++++- src/pages/FeedbackMessagePage/index.tsx | 15 +++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 src/pages/FeedbackMessagePage/index.tsx diff --git a/src/App.tsx b/src/App.tsx index 756d3bf..146ec23 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,15 +1,19 @@ import React, { FC } from 'react'; import { Route, Switch } from 'react-router-dom'; +import PrivateRoute from './components/common/PrivateRoute'; import ErrorBoundary from './components/common/ErrorBoundary'; + import Uri from './constants/uri'; + import HomePage from './pages/HomePage'; import NotFoundPage from './pages/NotFoundPage'; import ServiceEditPage from './pages/ServiceEditPage'; import ServicePage from './pages/ServicePage'; import SigninPage from './pages/SigninPage'; import SignupPage from './pages/SignupPage'; -import PrivateRoute from './components/common/PrivateRoute'; +import FeedbackMessagePage from './pages/FeedbackMessagePage'; + import { useUserStateValue } from './atoms/userState'; const App: FC = () => { @@ -39,7 +43,15 @@ const App: FC = () => { component={ServicePage} isAccessible={isAuthenticated} /> + + {/* + @TODO PrivateRoute로 변경 + 요 두 개의 페이지는 원래 Private으로 가야 하지만 아직은 테스트 용이성을 위해 Route로 남깁니다. + 추후 채팅을 구현할 때 PrivateRoute로 변경합시다! + */} + + diff --git a/src/pages/FeedbackMessagePage/index.tsx b/src/pages/FeedbackMessagePage/index.tsx new file mode 100644 index 0000000..24a7e24 --- /dev/null +++ b/src/pages/FeedbackMessagePage/index.tsx @@ -0,0 +1,15 @@ +import React, { FC } from 'react'; + +import SideLayout from '@/components/layout/SideLayout'; + +const FeedbackMessagePage: FC = () => { + return ( +
요기에는 채팅 중인 사용자 리스트
} + > + @TODO +
+ ); +}; + +export default FeedbackMessagePage; From d01eadda827a608f14043972ae7ca6b6a01c745b Mon Sep 17 00:00:00 2001 From: Yunseo Hwang Date: Sat, 1 Jan 2022 21:49:21 +0900 Subject: [PATCH 13/18] =?UTF-8?q?[#67]=20refactor:=20=EC=84=9C=EB=B9=84?= =?UTF-8?q?=EC=8A=A4=20=EC=88=98=EC=A0=95=20=ED=8E=98=EC=9D=B4=EC=A7=80?= =?UTF-8?q?=EC=97=90=EC=84=9C=20Layout=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=20=EB=8C=80=EC=8B=A0=20SideLayout=20=EC=BB=B4?= =?UTF-8?q?=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/ServiceEditPage/index.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pages/ServiceEditPage/index.tsx b/src/pages/ServiceEditPage/index.tsx index d05d122..5cd1a3f 100644 --- a/src/pages/ServiceEditPage/index.tsx +++ b/src/pages/ServiceEditPage/index.tsx @@ -1,6 +1,6 @@ import React, { FC, useEffect, useState } from 'react'; -import Layout from '@/components/layout/Layout'; +import SideLayout from '@/components/layout/SideLayout'; import ServiceEditForm from '@/components/service/ServiceEditForm'; import { ServiceInfo } from '@/types/service'; @@ -14,13 +14,13 @@ const ServiceEditPage: FC = () => { }, []); return ( - + {serviceInfo ? ( ) : (
Loading
)} -
+
); }; From 1c3d672bdbda7940c313fc1e8d85341d2ab60037 Mon Sep 17 00:00:00 2001 From: Yunseo Hwang Date: Sat, 1 Jan 2022 22:51:40 +0900 Subject: [PATCH 14/18] =?UTF-8?q?[#67]=20test:=20storybook=20decorator?= =?UTF-8?q?=EC=97=90=20BrowserRouter=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .storybook/preview.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.storybook/preview.js b/.storybook/preview.js index c145986..d6614ba 100644 --- a/.storybook/preview.js +++ b/.storybook/preview.js @@ -2,6 +2,7 @@ import { RecoilRoot } from 'recoil'; import { ThemeProvider } from '@emotion/react'; import GlobalStyle from '../src/styles/global'; import theme from '../src/styles/theme'; +import { BrowserRouter } from 'react-router-dom'; export const parameters = { actions: { argTypesRegex: '^on[A-Z].*' }, @@ -18,7 +19,9 @@ export const decorators = [ - + + + ), From 278ffbe44af2adebc196948ef0503c3aa3860fa1 Mon Sep 17 00:00:00 2001 From: Yunseo Hwang Date: Sat, 1 Jan 2022 22:52:33 +0900 Subject: [PATCH 15/18] =?UTF-8?q?[#67]=20test:=20storybook=20=EB=B6=84?= =?UTF-8?q?=EB=A5=98=EB=A5=BC=20Page=20=EB=8C=80=EC=8B=A0=20Components=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/stories/Page.stories.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/stories/Page.stories.tsx b/src/stories/Page.stories.tsx index ef313cb..28d64c0 100644 --- a/src/stories/Page.stories.tsx +++ b/src/stories/Page.stories.tsx @@ -4,7 +4,7 @@ import { ComponentStory, ComponentMeta } from '@storybook/react'; import Jumbotron from '@/components/common/Jumbotron'; export default { - title: 'Example/Page', + title: 'Example/Components', component: Jumbotron, } as ComponentMeta; @@ -12,8 +12,8 @@ const Template: ComponentStory = (args) => ( ); -export const TelbbyJumboTron = Template.bind({}); -TelbbyJumboTron.args = { +export const JumboTronExample = Template.bind({}); +JumboTronExample.args = { title: 'Talk', descList: ['프로젝트 피드백을 고민하고 있나요?', 'telbby에게 말해보세요'], }; From c1cfb8ec643cb4677f63012b3f57ead6e462249d Mon Sep 17 00:00:00 2001 From: Yunseo Hwang Date: Sat, 1 Jan 2022 22:53:06 +0900 Subject: [PATCH 16/18] =?UTF-8?q?[#67]=20test:=20IconTabBar=20storybook=20?= =?UTF-8?q?story=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/stories/IconTabBar.stories.tsx | 31 ++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 src/stories/IconTabBar.stories.tsx diff --git a/src/stories/IconTabBar.stories.tsx b/src/stories/IconTabBar.stories.tsx new file mode 100644 index 0000000..76af64c --- /dev/null +++ b/src/stories/IconTabBar.stories.tsx @@ -0,0 +1,31 @@ +import React from 'react'; +import { ComponentStory, ComponentMeta } from '@storybook/react'; + +import IconTabBar from '@/components/common/IconTabBar'; + +import ChatIcon from '@/assets/images/chat-icon.svg'; +import SettingIcon from '@/assets/images/setting-icon.svg'; + +export default { + title: 'Example/Components', + component: IconTabBar, +} as ComponentMeta; + +const Template: ComponentStory = (args) => { + return ( + + + Settings + + + Feedback Messages + + + Settings + + + ); +}; + +export const IconTabBarExample: ComponentStory = + Template.bind({}); From 3d843aa5f9102bf50afae9abf0b6c0f1c43d1d79 Mon Sep 17 00:00:00 2001 From: Yunseo Hwang Date: Sat, 1 Jan 2022 22:55:06 +0900 Subject: [PATCH 17/18] =?UTF-8?q?[#67]=20refactor:=20Page.stories.tsx?= =?UTF-8?q?=EB=A5=BC=20Jumbotron.stories.tsx=EB=A1=9C=20=EB=84=A4=EC=9D=B4?= =?UTF-8?q?=EB=B0=8D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/stories/{Page.stories.tsx => Jumbotron.stories.tsx} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/stories/{Page.stories.tsx => Jumbotron.stories.tsx} (100%) diff --git a/src/stories/Page.stories.tsx b/src/stories/Jumbotron.stories.tsx similarity index 100% rename from src/stories/Page.stories.tsx rename to src/stories/Jumbotron.stories.tsx From d6c9cf644584865f26dc911d36d91ac548bac9bb Mon Sep 17 00:00:00 2001 From: Yunseo Hwang Date: Sat, 1 Jan 2022 23:00:36 +0900 Subject: [PATCH 18/18] =?UTF-8?q?[#67]=20test:=20Sidebar=20storybook=20sto?= =?UTF-8?q?ry=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/stories/Sidebar.stories.tsx | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 src/stories/Sidebar.stories.tsx diff --git a/src/stories/Sidebar.stories.tsx b/src/stories/Sidebar.stories.tsx new file mode 100644 index 0000000..f1846e7 --- /dev/null +++ b/src/stories/Sidebar.stories.tsx @@ -0,0 +1,18 @@ +import React from 'react'; +import { ComponentStory, ComponentMeta } from '@storybook/react'; + +import Sidebar from '@/components/nav/Sidebar'; + +export default { + title: 'Example/Components', + component: Sidebar, +} as ComponentMeta; + +const Template: ComponentStory = (args) => { + return ; +}; + +export const SidebarExample: ComponentStory = Template.bind({}); +SidebarExample.args = { + children: 'Sidebar Contents', +};