Skip to content

Commit

Permalink
[Feat] SideNavBar 구현 (#293)
Browse files Browse the repository at this point in the history
* docs: svg 파일 추가

* feat: snb 내부 item 컴포넌트 구현

* refactor: PageIndicatorStick 리펙토링

* feat: SideNavBar 구현

* fix: SideNavBar 적용

* chore: merge develop

* feat: SNB item storybook 작성

* chore: 사소한 변경

* refactor: 레싸바 장례식ㅠ

* chore: SideNavBar 적용

* fix: 코드리뷰 반영

* fix: build 에러 해결

* feat: framer-motion 적용

* chore: conflict 해결
  • Loading branch information
rtttr1 authored Oct 31, 2024
1 parent 354b5a1 commit aee35e7
Show file tree
Hide file tree
Showing 24 changed files with 362 additions and 284 deletions.
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
"@tanstack/react-query": "^5.49.2",
"@tanstack/react-query-devtools": "^5.49.2",
"axios": "^1.7.2",
"framer-motion": "^11.11.9",
"mime": "^4.0.4",
"react": "^18.3.1",
"react-dom": "^18.3.1",
Expand Down
24 changes: 0 additions & 24 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import GlobalDrawer from '@/shared/component/GlobalDrawer/GlobalDrawer';
import Header from '@/shared/component/Header/Header';
import Login from '@/shared/component/Login/Login';
import ModalContainer from '@/shared/component/Modal/ModalContainer';
import SNB from '@/shared/component/SideNavBar/LeftSidebar';
import SideNavBar from '@/shared/component/SideNavBar/SideNavBar';
import { HTTP_STATUS_CODE } from '@/shared/constant/api';
import { PATH } from '@/shared/constant/path';
import ErrorPage from '@/shared/page/errorPage/ErrorPage';
Expand Down Expand Up @@ -50,7 +50,9 @@ const App = () => {
<ErrorBoundary fallback={ErrorPage} onReset={handleResetError}>
<Login>
<ModalContainer />
<SNB />

<SideNavBar />

<div css={layoutStyle}>
<main css={outletStyle}>
<Header />
Expand Down
6 changes: 4 additions & 2 deletions src/common/asset/svg/ic_add.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions src/common/asset/svg/ic_avatar.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 9 additions & 2 deletions src/common/asset/svg/ic_global.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions src/common/asset/svg/ic_tiki_logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 6 additions & 2 deletions src/common/component/ToolTip/ToolTip.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import { ToolTipProps } from '@/common/component/ToolTip/ToolTip';
import { theme } from '@/common/style/theme/theme';

export const containerStyle = css({
display: 'inline-block',
position: 'relative',
border: '1px solid',
});

export const messageStyle = (isVisible: boolean) =>
Expand All @@ -16,12 +16,16 @@ export const messageStyle = (isVisible: boolean) =>
padding: '1rem',
borderRadius: '8px',

zIndex: theme.zIndex.overlayTop,

backgroundColor: `${theme.colors.gray_900}`,
font: `${theme.text.body08}`,
color: `${theme.colors.white}`,

visibility: isVisible ? 'visible' : 'hidden',
transitionDelay: '0.2s',

transitionDelay: isVisible ? '0.2s' : '0',

pointerEvents: 'none',
});

Expand Down
2 changes: 1 addition & 1 deletion src/common/component/ToolTip/ToolTip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const ToolTip = ({ position = 'right', message, gap = 0, children, ...props }: T
aria-describedby={message}
role="button"
css={containerStyle}
tabIndex={0}
tabIndex={-1}
onMouseEnter={handleToolTipVisible}
onMouseLeave={handleToolTipHidden}
onKeyDown={handleKeyDown}
Expand Down
2 changes: 2 additions & 0 deletions src/common/style/theme/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ const colors = {

key_600: '#444EE4',
key_500: '#6D77FF',
key_400: '#99ACFF',
key_300: '#B9C7FF',
key_200: '#E3E8FF',
key_100: '#F3F5FF',

Expand Down
43 changes: 43 additions & 0 deletions src/shared/component/SideNavBar/Item/Item.style.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { css } from '@emotion/react';

import { theme } from '@/common/style/theme/theme';

export const itemStyle = (isClicked: boolean) =>
css({
display: 'flex',
alignItems: 'center',
justifyContent: 'center',

width: '3.6rem',
height: '3.6rem',
padding: '0.1rem',

backgroundColor: theme.colors.gray_100,
borderRadius: '10px',
border: isClicked ? `1px solid ${theme.colors.key_500}` : 0,

'&:hover': {
border: `1px solid ${theme.colors.key_500}`,
},

cursor: 'pointer',
});

export const indicatorStyle = css({
position: 'absolute',
left: 0,
});

export const firstSpellStyle = css({
font: `${theme.text.body06}`,
color: theme.colors.gray_500,
});

export const pageIndicatorStyle = (isClicked: boolean, isHover: boolean) =>
css({
width: '0.4rem',
height: isClicked ? '2.4rem' : isHover ? '1.6rem' : 0,

borderRadius: '0 100px 100px 0',
backgroundColor: isClicked ? theme.colors.key_500 : isHover ? theme.colors.key_300 : theme.colors.white,
});
60 changes: 60 additions & 0 deletions src/shared/component/SideNavBar/Item/Item.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { motion } from 'framer-motion';

import { HTMLAttributes, useState } from 'react';

import Flex from '@/common/component/Flex/Flex';
import ToolTip from '@/common/component/ToolTip/ToolTip';

import {
firstSpellStyle,
indicatorStyle,
itemStyle,
pageIndicatorStyle,
} from '@/shared/component/SideNavBar/Item/Item.style';

interface ItemProps extends HTMLAttributes<HTMLDivElement> {
hoverMessage: string;
logoUrl: string | null;
isClicked: boolean;
onLogoClick: () => void;
}

const Item = ({ logoUrl = '', isClicked, onLogoClick, hoverMessage, ...props }: ItemProps) => {
const [isHover, setIsHover] = useState(false);

const handleMouseEnter = () => {
setIsHover(true);
};

const handleMouseLeave = () => {
setIsHover(false);
};

const handleEnterKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {
if (e.key === 'Enter') {
onLogoClick();
}
};

return (
<Flex tag="li" styles={{ align: 'center', justify: 'center', padding: '2rem' }} {...props}>
{isClicked && (
<motion.div layoutId="snb_indicator" css={[pageIndicatorStyle(isClicked, isHover), indicatorStyle]} />
)}
<ToolTip message={hoverMessage} position="right" gap={0.8}>
<div
role="button"
tabIndex={0}
css={itemStyle(isClicked)}
onClick={onLogoClick}
onKeyDown={handleEnterKeyDown}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}>
{logoUrl ? <img src={logoUrl} alt="버튼 아이콘" /> : <span css={firstSpellStyle}>{hoverMessage[0]}</span>}
</div>
</ToolTip>
</Flex>
);
};

export default Item;
54 changes: 0 additions & 54 deletions src/shared/component/SideNavBar/LeftSidebar.style.ts

This file was deleted.

Loading

0 comments on commit aee35e7

Please sign in to comment.