Skip to content

Commit

Permalink
feat(blog): 블로그 컴포넌트(header) 작업 중 #35
Browse files Browse the repository at this point in the history
  • Loading branch information
JaeSeoKim committed Apr 23, 2022
1 parent 0997fcd commit 5a7523d
Show file tree
Hide file tree
Showing 10 changed files with 332 additions and 111 deletions.
24 changes: 21 additions & 3 deletions packages/blog/components/Header/Header.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,31 @@ export default {
const Template: ComponentStory<typeof Header> = (args) => (
<div
style={{
position: 'relative',
boxSizing: 'border-box',
height: '200vh',
height: '500vh',
}}
>
<Header {...args} />
</div>
)

export const Primary = Template.bind({})
Primary.args = {}
export const Home = Template.bind({})
Home.args = {}
Home.parameters = {
nextRouter: {
pathname: '/',
asPath: '/',
query: {},
},
}

export const OtherPage = Template.bind({})
OtherPage.args = {}
OtherPage.parameters = {
nextRouter: {
pathname: '/other-page',
asPath: '/other-page',
query: {},
},
}
61 changes: 40 additions & 21 deletions packages/blog/components/Header/Header.styled.tsx
Original file line number Diff line number Diff line change
@@ -1,52 +1,71 @@
import { motion } from 'framer-motion'
import styled from 'styled-components'
import styled, { css } from 'styled-components'
import { breakPoint } from '../../styles/theme'

export const mediaPadding = css`
padding: 16px 32px;
`

const Styled = {
rootContainer: styled(motion.header)`
position: fixed;
position: sticky;
top: 0;
left: 0;
z-index: 1;
display: flex;
width: 100%;
`,
mainContainer: styled(motion.div)`
wrapContainer: styled(motion.div)`
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
max-width: 1536px;
padding: 8px 16px;
${mediaPadding}
width: 100%;
max-width: 1280px;
margin-left: auto;
margin-right: auto;
`,
leftContainer: styled(motion.div)`
flexContainer: styled(motion.div)`
display: flex;
align-items: center;
gap: 8px;
`,
image: styled(motion.img)`
border-radius: 50%;
`,
infoContainer: styled(motion.div)`
anchor: styled(motion.a)`
display: flex;
flex-direction: column;
gap: 8px;
align-items: center;
gap: 4px;
color: inherit;
text-decoration: inherit;
`,
icon: styled(motion.img)`
border-radius: 50%;
width: 32px;
height: 32px;
display: block;
@media screen and (max-width: ${breakPoint.md}px) {
display: none;
}
`,
title: styled(motion.h1)`
margin: 0;
margin-top: auto;
margin-bottom: auto;
font-weight: 600;
`,
subtitle: styled(motion.h2)`
margin: 0;
font-weight: 400;
`,
rigthContainer: styled(motion.div)`
display: flex;
menu: styled(motion.div)`
display: none;
@media screen and (max-width: ${breakPoint.md}px) {
display: flex;
}
`,
search: styled(motion.div)``,
}

export default Styled
142 changes: 66 additions & 76 deletions packages/blog/components/Header/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,32 @@
import React, { useState } from 'react'
import { useViewportScroll, MotionConfig } from 'framer-motion'
import React, { useEffect, useState } from 'react'
import { MotionConfig, LayoutGroup } from 'framer-motion'
import Styled from './Header.styled'
import Link from 'next/link'
import Hero from './Hero'
import { useRouter } from 'next/router'

const image = {
src: 'https://avatars.githubusercontent.com/u/48559454?v=4',
alt: "JaeSeoKim's avatar",
}

const title = 'JaeSeoKim'
const subtitle = '🎢 To become a better developer...!'

export type HeaderProps = {}

const Header: React.FC<HeaderProps> = ({}) => {
const { scrollY } = useViewportScroll()
const [isHero, setIsHero] = useState(scrollY.get() < 200)
const router = useRouter()
const [isHome, setIsHome] = useState(router.pathname === '/')
const [isShowHero, setIsShowHero] = useState(false)

scrollY.onChange((value) => {
if (value < 200) {
setIsHero(true)
useEffect(() => {
if (router.pathname === '/') {
setIsHome(true)
} else {
setIsHero(false)
setIsHome(false)
}
})
}, [router.pathname])

return (
<MotionConfig
Expand All @@ -23,73 +35,51 @@ const Header: React.FC<HeaderProps> = ({}) => {
type: 'tween',
}}
>
<Styled.rootContainer
initial={scrollY.get() < 200 ? 'hero' : 'header'}
animate={isHero ? 'hero' : 'header'}
variants={{
hero: {
paddingTop: '64px',
backgroundColor: '#ffffff',
boxShadow: `0px`,
},
header: {
paddingTop: '0px',
backgroundColor: '#F5F5F7',
boxShadow: `0px 1px 2px rgba(0, 0, 0, 0.25)`,
},
}}
>
<Styled.mainContainer>
<Styled.leftContainer>
<Styled.image
src="https://avatars.githubusercontent.com/u/48559454?v=4"
alt="JaeSeoKim's avatar"
variants={{
hero: {
width: '200px',
height: '200px',
},
header: {
width: '36px',
height: '36px',
},
}}
/>
<Styled.infoContainer>
<Styled.title
variants={{
hero: {
fontSize: '36px',
},
header: {
fontSize: '24px',
},
}}
>
JaeSeoKim
</Styled.title>
<Styled.subtitle
variants={{
hero: {
fontSize: '24px',
opacity: 1,
scale: 1,
display: 'flex',
},
header: {
opacity: 0,
scale: 0,
display: 'none',
},
}}
>
Frontend Developer
</Styled.subtitle>
</Styled.infoContainer>
</Styled.leftContainer>
<Styled.rigthContainer>right</Styled.rigthContainer>
</Styled.mainContainer>
</Styled.rootContainer>
<LayoutGroup>
<Styled.rootContainer
initial={[isShowHero ? 'hero' : 'header']}
animate={[isShowHero ? 'hero' : 'header']}
variants={{
hero: {
boxShadow: `0px`,
backgroundColor: `rgba(255, 255, 255, 0)`,
},
header: {
boxShadow: `rgb(0 0 0 0.2) 0px 1px 15px`,
backgroundColor: `#F5F5F7`,
},
}}
>
<Styled.wrapContainer>
<Styled.menu>menu</Styled.menu>
<Styled.flexContainer>
{!isShowHero && (
<Link href={'/'} passHref>
<Styled.anchor>
<Styled.icon layoutId={`${router.pathname}-image`} src={image.src} alt={image.alt} />
<Styled.title layoutId={`${router.pathname}-title`}>{title}</Styled.title>
</Styled.anchor>
</Link>
)}
</Styled.flexContainer>
<Styled.flexContainer>right</Styled.flexContainer>
</Styled.wrapContainer>
</Styled.rootContainer>
{isHome && (
<Hero
image={image}
title={title}
subtitle={subtitle}
onViewportEnter={() => {
setIsShowHero(true)
}}
onViewportLeave={() => {
setIsShowHero(false)
}}
pathname={router.pathname}
/>
)}
</LayoutGroup>
</MotionConfig>
)
}
Expand Down
65 changes: 65 additions & 0 deletions packages/blog/components/Header/Hero/Hero.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { ComponentMeta, ComponentStory } from '@storybook/react'

import Hero from './Hero'

export default {
title: 'Components/Header/Hero',
component: Hero,
} as ComponentMeta<typeof Hero>

const Template: ComponentStory<typeof Hero> = (args) => <Hero {...args} />

export const Default = Template.bind({})
Default.args = {
title: 'Hello World',
subtitle: 'This is a subtitle',
image: {
src: 'https://images.unsplash.com/photo-1497316730643-415fac54a2af?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=928&q=80',
alt: 'Photo by Michael Henry',
},
}

export const Mobile1 = Template.bind({})
Mobile1.args = {
title: 'Hello World',
subtitle: 'This is a subtitle',
image: {
src: 'https://images.unsplash.com/photo-1497316730643-415fac54a2af?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=928&q=80',
alt: 'Photo by Michael Henry',
},
}
Mobile1.parameters = {
viewport: {
defaultViewport: 'mobile1',
},
}

export const Mobile2 = Template.bind({})
Mobile2.args = {
title: 'Hello World',
subtitle: 'This is a subtitle',
image: {
src: 'https://images.unsplash.com/photo-1497316730643-415fac54a2af?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=928&q=80',
alt: 'Photo by Michael Henry',
},
}
Mobile2.parameters = {
viewport: {
defaultViewport: 'mobile2',
},
}

export const Tablet = Template.bind({})
Tablet.args = {
title: 'Hello World',
subtitle: 'This is a subtitle',
image: {
src: 'https://images.unsplash.com/photo-1497316730643-415fac54a2af?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=928&q=80',
alt: 'Photo by Michael Henry',
},
}
Tablet.parameters = {
viewport: {
defaultViewport: 'tablet',
},
}
Loading

0 comments on commit 5a7523d

Please sign in to comment.