-
Notifications
You must be signed in to change notification settings - Fork 7
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
[SP3] 메인 하단 레이아웃 #324
[SP3] 메인 하단 레이아웃 #324
Changes from 5 commits
39f2f19
0feb88f
cbb2e1f
b75f878
a6f34e8
6f62e10
77891e4
af5a788
5fc2c82
dcdb2ad
f7617ff
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { forwardRef } from 'react'; | ||
import Activity from '@src/views/MainPage/components/Activity'; | ||
import OwnOrganization from '@src/views/MainPage/components/OwnOrganization'; | ||
import PartConfig from '@src/views/MainPage/components/PartConfig'; | ||
import * as S from './style'; | ||
|
||
function ActivitySection(_props: unknown, ref: React.Ref<HTMLDivElement>) { | ||
return ( | ||
<S.Wrapper id="activity" ref={ref}> | ||
<Activity /> | ||
Comment on lines
+7
to
+10
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. Activity 컴포넌트에 활동 내역이 담겨있어서 Activity라고 명을 지었는데, 메뉴에서 활동/파트/자체기구를 합친 명이 Activity 군요..! 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. 저도 찬성해요!!! |
||
<PartConfig /> | ||
<OwnOrganization /> | ||
</S.Wrapper> | ||
); | ||
} | ||
|
||
export default forwardRef(ActivitySection); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import styled from '@emotion/styled'; | ||
|
||
export const Wrapper = styled.div` | ||
display: flex; | ||
flex-direction: column; | ||
gap: 146px; | ||
|
||
margin-bottom: 300px; | ||
`; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import { useScroll, useTransform } from 'framer-motion'; | ||
import { RefObject, useRef } from 'react'; | ||
import useInView from '@src/hooks/useInView'; | ||
import ActivitySection from '@src/views/MainPage/components/ActivitySection'; | ||
import * as S from './style'; | ||
|
||
const MenuList = [ | ||
{ name: 'Value', id: 'value' }, | ||
{ name: 'Activity', id: 'activity' }, | ||
{ name: 'Review', id: 'review' }, | ||
{ name: 'Recent news', id: 'news' }, | ||
]; | ||
|
||
export type RefHandler = { | ||
viewRef: RefObject<HTMLDivElement>; | ||
targetRef: RefObject<HTMLDivElement>; | ||
}; | ||
|
||
function BottomLayout() { | ||
const activity = useInView(); | ||
const review = useInView(); | ||
const news = useInView(); | ||
|
||
const targetRef = useRef<HTMLDivElement>(null); | ||
const { scrollYProgress } = useScroll({ target: targetRef, offset: ['start center', 'start'] }); | ||
|
||
const viewList = [false, activity.isInView, review.isInView, news.isInView]; | ||
const minIndex = viewList.findIndex((value) => value === true); | ||
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. minIndex 의 의미는 무엇인가요? 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. |
||
|
||
const wrapperBackground = useTransform(scrollYProgress, [0, 1], ['#FFF', '#090B12']); | ||
const layoutBackground = useTransform(scrollYProgress, [0, 1], ['#F6F8FC', '#0D111F']); | ||
const menuBackground = useTransform(scrollYProgress, [0, 1], ['#fbfcfe', '#fbfcfef']); | ||
const menuColor = useTransform(scrollYProgress, [0, 1], ['#a8acbae0', '#747885']); | ||
|
||
return ( | ||
<S.Wrapper style={{ backgroundColor: wrapperBackground }}> | ||
<S.FloatingMenu> | ||
{MenuList.map(({ name, id }, index) => ( | ||
<S.MenuWrapper | ||
key={id} | ||
isInView={minIndex === index} | ||
style={{ backgroundColor: menuBackground, color: menuColor }} | ||
> | ||
<S.Menu href={`#${id}`}>{name}</S.Menu> | ||
</S.MenuWrapper> | ||
))} | ||
</S.FloatingMenu> | ||
<S.Layout style={{ backgroundColor: layoutBackground }}> | ||
<ActivitySection ref={activity.ref} /> | ||
<div ref={targetRef} /> | ||
<div id="review" ref={review.ref} style={{ height: '100vh', background: 'blue' }}> | ||
Reviews | ||
</div> | ||
<div id="news" ref={news.ref} style={{ height: '100vh', background: 'yellow' }}> | ||
News | ||
</div> | ||
</S.Layout> | ||
</S.Wrapper> | ||
); | ||
} | ||
|
||
export default BottomLayout; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
import styled from '@emotion/styled'; | ||
import { colors } from '@sopt-makers/colors'; | ||
import { motion } from 'framer-motion'; | ||
import Link from 'next/link'; | ||
import { css } from '@emotion/react'; | ||
import icPolygon from '@src/assets/icons/ic_polygon.svg'; | ||
|
||
export const Wrapper = styled(motion.section)` | ||
display: flex; | ||
gap: 12.25px; | ||
|
||
width: 100%; | ||
padding: 0 2.86vw; | ||
background-color: ${colors.white}; | ||
|
||
@media (max-width: 768px) { | ||
padding: 0 5.98vw; | ||
} | ||
`; | ||
|
||
export const FloatingMenu = styled.div` | ||
display: flex; | ||
flex-direction: column; | ||
gap: 9.27px; | ||
position: sticky; | ||
top: 0; | ||
|
||
height: fit-content; | ||
|
||
@media (max-width: 768px) { | ||
display: none; | ||
} | ||
`; | ||
|
||
export const MenuWrapper = styled(motion.div)<{ isInView?: boolean }>` | ||
position: relative; | ||
|
||
background-color: #fbfcfe; | ||
border-radius: 10px; | ||
border: 1.2px solid rgba(196, 199, 211, 0.3); | ||
|
||
color: rgba(168, 172, 186, 0.88); | ||
text-align: center; | ||
font-family: SUIT; | ||
font-size: 19.46px; | ||
font-style: normal; | ||
font-weight: 500; | ||
line-height: 53.54px; /* 275.126% */ | ||
letter-spacing: -0.584px; | ||
|
||
${({ isInView }) => | ||
isInView && | ||
css` | ||
border-color: transparent; | ||
background-color: #24314d !important; | ||
color: #fff !important; | ||
|
||
&::after { | ||
content: ''; | ||
position: absolute; | ||
top: 50%; | ||
right: -8px; | ||
transform: translateY(-50%); | ||
z-index: 99; | ||
|
||
width: 8px; | ||
height: 11px; | ||
background-image: url(${icPolygon}); | ||
background-repeat: no-repeat; | ||
} | ||
`}; | ||
`; | ||
|
||
export const Menu = styled(Link)` | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
|
||
width: 190px; | ||
height: 72px; | ||
|
||
@media (max-width: 1440px) { | ||
width: 152px; | ||
} | ||
`; | ||
|
||
export const Layout = styled(motion.div)` | ||
flex: 1; | ||
width: 80%; | ||
padding: 68px 4vw 0 4vw; | ||
border-radius: 20.946px; | ||
background: #f6f8fc; | ||
|
||
@media (max-width: 768px) { | ||
padding: 65px 6.25vw 0 6.25vw; | ||
} | ||
|
||
@media (max-width: 428px) { | ||
padding: 37.36px 28px 0 28px; | ||
} | ||
`; |
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.