-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feat: Card & Text & NavigationHeader 구현 #13
Changes from all commits
8b7a637
520bf87
18f2626
7b5a082
0893f74
19d4f79
86a6855
9646350
e40906b
fbaea37
e0f754c
801263e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import { SvgProps } from '../nav/SettingIcon'; | ||
|
||
export const Avatar = ({ className, ...props }: SvgProps) => { | ||
return ( | ||
<svg | ||
width="60" | ||
height="60" | ||
viewBox="0 0 60 60" | ||
fill="none" | ||
xmlns="http://www.w3.org/2000/svg" | ||
className={className} | ||
{...props} | ||
> | ||
<circle cx="30" cy="30" r="30" fill="#8D9199" /> | ||
<path | ||
d="M36.6667 24.6667C36.6667 28.3486 33.6819 31.3333 30 31.3333C26.3181 31.3333 23.3333 28.3486 23.3333 24.6667C23.3333 20.9848 26.3181 18 30 18C33.6819 18 36.6667 20.9848 36.6667 24.6667Z" | ||
fill="white" | ||
/> | ||
<path | ||
d="M19.3333 40.6667C19.3333 36.9848 22.3181 34 26 34H34C37.6819 34 40.6667 36.9848 40.6667 40.6667C40.6667 41.403 40.0697 42 39.3333 42H20.6667C19.9303 42 19.3333 41.403 19.3333 40.6667Z" | ||
fill="white" | ||
/> | ||
</svg> | ||
); | ||
}; |
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { SvgProps } from './SettingIcon'; | ||
|
||
export const BackIcon = ({ className, ...props }: SvgProps) => { | ||
return ( | ||
<svg | ||
width="24" | ||
height="24" | ||
viewBox="0 0 24 24" | ||
fill="none" | ||
xmlns="http://www.w3.org/2000/svg" | ||
className={className} | ||
{...props} | ||
> | ||
<path | ||
d="M8.55439 11.5271L15.1552 17.0659C15.5783 17.4209 15.6335 18.0517 15.2785 18.4747C14.9235 18.8978 14.2927 18.953 13.8696 18.598L6.36322 12.2993C6.30343 12.2492 6.25099 12.1935 6.20601 12.1337C5.88238 11.7115 5.9458 11.1052 6.35736 10.7599L13.8646 4.46054C14.2877 4.10554 14.9184 4.16072 15.2734 4.5838C15.6284 5.00687 15.5732 5.63763 15.1502 5.99263L8.55439 11.5271Z" | ||
fill="#333333" | ||
/> | ||
</svg> | ||
); | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { SvgProps } from './SettingIcon'; | ||
|
||
export const CloseIcon = ({ className, ...props }: SvgProps) => { | ||
return ( | ||
<svg | ||
xmlns="http://www.w3.org/2000/svg" | ||
width="24" | ||
height="24" | ||
viewBox="0 0 24 24" | ||
fill="none" | ||
className={className} | ||
{...props} | ||
> | ||
<path | ||
d="M6.12117 4.7072C5.73064 4.31668 5.09748 4.31668 4.70696 4.7072C4.31643 5.09772 4.31643 5.73089 4.70696 6.12141L10.3639 11.7783L4.70706 17.4351C4.31654 17.8256 4.31654 18.4588 4.70706 18.8493C5.09758 19.2399 5.73075 19.2399 6.12127 18.8493L11.7781 13.1925L17.4349 18.8493C17.8254 19.2399 18.4586 19.2399 18.8491 18.8493C19.2396 18.4588 19.2396 17.8256 18.8491 17.4351L13.1923 11.7783L18.8492 6.12141C19.2397 5.73089 19.2397 5.09772 18.8492 4.7072C18.4587 4.31668 17.8255 4.31668 17.435 4.7072L11.7781 10.3641L6.12117 4.7072Z" | ||
fill="#1C1C1E" | ||
/> | ||
</svg> | ||
); | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import type { ReactNode } from 'react'; | ||
import clsx from 'clsx'; | ||
import { type RouteInfo } from '@/shared/hooks'; | ||
import RouteMove from '../RouteMove'; | ||
|
||
interface LeftContentProps extends RouteInfo { | ||
className?: string; | ||
children: ReactNode; | ||
} | ||
|
||
function Root({ className, children }: Omit<LeftContentProps, 'location'>) { | ||
return ( | ||
<header | ||
className={clsx('flex justify-between px-5 py-4 items-center', className)} | ||
> | ||
{children} | ||
</header> | ||
); | ||
} | ||
|
||
function LeftContent({ location, className, children }: LeftContentProps) { | ||
return ( | ||
<RouteMove location={location} className={clsx(className)}> | ||
{children} | ||
</RouteMove> | ||
); | ||
} | ||
|
||
function RightContent({ location, className, children }: LeftContentProps) { | ||
return ( | ||
<RouteMove location={location} className={clsx(className)}> | ||
{children} | ||
</RouteMove> | ||
); | ||
} | ||
|
||
const NavigationHeader = Object.assign(Root, { LeftContent, RightContent }); | ||
|
||
export default NavigationHeader; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import type { ComponentProps, ReactNode } from 'react'; | ||
import { type RouteInfo, useMoveLocation } from '@/shared/hooks'; | ||
|
||
interface RouteMoveProps extends RouteInfo, ComponentProps<'div'> { | ||
children: ReactNode; | ||
} | ||
|
||
export default function RouteMove({ | ||
location, | ||
children, | ||
...props | ||
}: RouteMoveProps) { | ||
const handleMoveLocation = useMoveLocation(location); | ||
|
||
return ( | ||
<div onClick={handleMoveLocation} {...props}> | ||
{children} | ||
</div> | ||
); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
export { default as NavigationHeader } from './NavigationHeader'; | ||
export { default as PrimaryChips } from './Chips'; | ||
export { default as Button } from './Buttons'; | ||
export { default as RouteMove } from './RouteMove'; | ||
Comment on lines
+1
to
+4
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이렇게 index에 한데 모아서 export 하는 이유가 뭘까요? |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './useMoveLocation'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { useCallback } from 'react'; | ||
import { useNavigate } from 'react-router'; | ||
|
||
const routeMap = { | ||
home: '/', | ||
setting: '/setting', | ||
onboarding: '/onboarding', | ||
detail: '/detail', | ||
userInfo: '/user-info', | ||
analysis: '/analysis', | ||
result: '/result', | ||
popular: '/result/popular', | ||
strengthWeakness: '/result/strength-weakness', | ||
growthPrediction: '/result/growth-prediction', | ||
strategy: '/result/strategy', | ||
} as const; | ||
|
||
export interface RouteInfo { | ||
location: (typeof routeMap)[keyof typeof routeMap] | 'back'; | ||
} | ||
|
||
export const useMoveLocation = (location: RouteInfo['location']) => { | ||
const navigate = useNavigate(); | ||
|
||
const handleMoveLocation = useCallback(() => { | ||
if (location === 'back') { | ||
navigate(-1); | ||
} else { | ||
navigate(location); | ||
} | ||
}, [navigate, location]); | ||
Comment on lines
+22
to
+31
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 외부 라이브러리로 부터의 결합성을 낮추는 이런 방식이 있군요! |
||
|
||
return handleMoveLocation; | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import type { ReactNode } from 'react'; | ||
import clsx from 'clsx'; | ||
|
||
interface RootProps { | ||
className?: string; | ||
children: ReactNode; | ||
} | ||
|
||
function Root({ className, children }: RootProps) { | ||
return ( | ||
<article | ||
className={clsx( | ||
`flex flex-col border rounded-2xl border-midEmphasis gap-y-5 overflow-hidden`, | ||
className, | ||
)} | ||
> | ||
{children} | ||
</article> | ||
); | ||
} | ||
|
||
function Header({ className, children }: RootProps) { | ||
return ( | ||
<div className={clsx(`flex flex-col px-5 pt-5 flex-1`, className)}> | ||
{children} | ||
</div> | ||
); | ||
} | ||
|
||
function Content({ className, children }: RootProps) { | ||
return ( | ||
<div | ||
className={clsx( | ||
`p-5 flex justify-between flex-2 gap-x-9 items-center`, | ||
className, | ||
)} | ||
> | ||
{children} | ||
</div> | ||
); | ||
} | ||
|
||
function Bottom({ className, children }: RootProps) { | ||
return <div className={clsx(`flex-1`, className)}>{children}</div>; | ||
} | ||
|
||
const Card = Object.assign(Root, { Header, Content, Bottom }); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이거 배워갑니다. 오픈 소스 라이브러리에서만 보던건데 너무 좋은데요? |
||
|
||
export default Card; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import clsx from 'clsx'; | ||
|
||
interface TextProps { | ||
as: keyof typeof style; | ||
title: string; | ||
className?: string; | ||
} | ||
|
||
const style = { | ||
title: 'text-black font-extrabold text-[15px] not-italic', | ||
description: 'text-gray font-medium text-[13px] not-italic', | ||
} as const; | ||
|
||
export default function Text({ as, title, className }: TextProps) { | ||
return <p className={clsx(style[as], className)}>{title}</p>; | ||
} | ||
Comment on lines
+1
to
+16
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Text 컴포넌트는 용도가 어떻게 될까요? 스크린샷이 있을까요? |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,7 @@ | ||
export { default as GlobalLayout } from './GlobalLayout'; | ||
export { default as Card } from './components/Card'; | ||
export { default as Text } from './components/Text'; | ||
|
||
export { default as GlobalLayout } from './layout/GlobalLayout'; | ||
export { default as BottomNavigationLayout } from './layout/BottomNavigationLayout'; | ||
export { default as PageLayout } from './layout/PageLayout'; | ||
export { default as ProtectedLayout } from './layout/ProtectedLayout'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이렇게 하니까 가독성이 좋아지네요