* {
box-sizing: border-box;
margin: 0;
padding: 0;
font-family: 'Encode Sans Expanded'
}
index.js와 NavbarElements 파일 생성
다음과 같이 index.js 작성
import React, {useState, useEffect} from 'react'
import { FaBars } from 'react-icons/fa'
import {IconContext} from 'react-icons/lib'
import { Nav, NavbarContainer, NavLogo, MobileIcon, NavMenu, NavLinks, NavItem, NavBtn, NavBtnLink } from './NavbarElements'
import { animateScroll as scroll } from 'react-scroll';
const Navbar = ({ toggle }) => {
const [scrollNav, setScrollNav] = useState(false)
const changeNav = () => {
if(window.scrollY >= 80) {
setScrollNav(true)
} else {
setScrollNav(false)
}
}
useEffect(() => {
window.addEventListener('scroll', changeNav)
}, [])
const toggleHome = () => {
scroll.scrollToTop();
}
return (
<>
<IconContext.Provider value={{ color: '#fff'}}>
<Nav scrollNav={scrollNav}>
<NavbarContainer>
<NavLogo to='/' onClick={toggleHome}>dolla</NavLogo>
<MobileIcon onClick={toggle}>
<FaBars />
</MobileIcon>
<NavMenu>
<NavItem>
<NavLinks to='about'
smooth={true} duration={500} spy={true} exact='true' offset={-80}
>About</NavLinks>
</NavItem>
<NavItem>
<NavLinks to='discover'
smooth={true} duration={500} spy={true} exact='true' offset={-80}
>Discover</NavLinks>
</NavItem>
<NavItem>
<NavLinks to='services'
smooth={true} duration={500} spy={true} exact='true' offset={-80}
>Services</NavLinks>
</NavItem>
<NavItem>
<NavLinks to='signup'
smooth={true} duration={500} spy={true} exact='true' offset={-80}
>Sign Up</NavLinks>
</NavItem>
</NavMenu>
<NavBtn>
<NavBtnLink to='/signin'>Sign In</NavBtnLink>
</NavBtn>
</NavbarContainer>
</Nav>
</IconContext.Provider>
</>
)
}
export default Navbar
1)
toggleHome 구현하기
animateScroll 구현하기
-NavLinks에 smooth와 duration, spy, exact, offset 등 추가하기
-activeclass에 active 값 넣어 구현할수도 있지만, 그냥 쥔장이 한대로 하자
-offset은 margin값에 따라 달라질 수 있다
4. src/pages/index.js 에 넣기
import styled from 'styled-components'
import { Link as LinkR } from 'react-router-dom'
import { Link as LinkS } from 'react-scroll'
export const Nav = styled.nav`
background: ${({scrollNav}) => (scrollNav ? '#000' : 'transparent')};
height: 80px;
margin-top: -80px;
display:flex;
justify-content: center;
align-items: center;
font-size: 1rem;
position: sticky;
top:0;
z-index:10;
@media screen and (max-width: 960px) {
transition: 0.8s all ease;
}
`
export const NavbarContainer = styled.div`
display: flex;
justify-content: space-between;
height: 80px;
z-index: 1;
width: 100%;
padding: 0 24px;
max-width: 1100px;
`
export const NavLogo = styled(LinkR) `
color:#fff;
justify-self: flex-start;
cursor: pointer;
font-size: 1.5rem;
display: flex;
align-items: center;
margin-left: 24px;
font-weight: bold;
text-decoration: none;
`
export const MobileIcon = styled.div`
display: none;
@media screen and (max-width: 768px) {
display: block;
position: absolute;
top: 0;
right: 0;
transform: translate(-100%, 60%);
font-size: 1.8rem;
cursor: pointer;
color: #fff;
}
`
export const NavMenu = styled.ul`
display:flex;
justify-content: center;
list-style: none;
text-align: center;
margin-right: -22px;
@media screen and (max-width: 768px) {
display: none;
}
`
export const NavItem = styled.li`
height: 80px;
`
export const NavLinks = styled(LinkS)`
color: #fff;
display: flex;
align-items: center;
text-decoration: none;
padding: 0 1rem;
height: 100%;
cursor: pointer;
&.active {
border-bottom: 3px solid #01bf71
}
`
export const NavBtn = styled.nav`
display: flex;
align-items: center;
@media screen and (max-width: 768px) {
display: none;
}
`
export const NavBtnLink = styled(LinkR)`
border-radius: 50px;
background: #01bf71;
white-space: nowrap;
padding: 10px 22px;
color: #010606;
font-size: 16px;
outline: none;
border: none;
cursor: pointer;
transition: all 0.2s ease-in-out;
text-decoration: none;
&:hover {
transition: all 0.2s ease-in-out;
background: #fff;
color: #010606;
}
`
3) scrollNav 설정
yarn add react-scroll
import styled from 'styled-components';
import {Link} from 'react-scroll'
import styled from 'styled-components';
import {Link} from 'react-scroll'
export const Button = styled(Link)`
border-radius: 50px;
background: ${({primary}) => (primary ? '#01BF71' : '#010606')};
white-space: nowrap;
padding: ${({big}) => (big ? '14px 48px' : '12px 30px')};
color: ${({dark}) => (dark ? '#010606' : '#fff')};
font-size:${({fontBig}) => (fontBig ? '20px' : '16px')};
outline: none;
border: none;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
transition: all 0.2s ease-in-out;
&:hover {
transition: all 0.2s ease-in-out;
background: ${({primary}) => (primary ? '#fff' : '#01BF71')};
}
`
-border-radius 값은 px로 고정이다
-background 값은 primary 값에 따라 바뀐다
-white-space는
-padding 값은 big 값에 따라 바뀐다
-color 값은 dark 값에 따라 바뀐다
-font-size 값은 fontBig 값에 따라 바뀐다
-border 값과 outline 값은 없앤다
-cursor는 pointer로 설정한다
-display 는 flex 고, 가로 추축 center, 세로 부축 center로 설정한다
-trainsition 효과를 준다.
-hover 가 들어올 경우, primary 값에 따라 background 값이 바뀐다
src/components/infoSection 폴터를 추가한다
infoSection 폴더 안에 index.js와 InFoElements.js(styled Components로 디자인하는 목적), Data.js 를 추가한다
index.js에 다음과 같은 내용을 추가한다.
import React from 'react'
import { Button } from '../ButtonElements'
import { InfoContainer, InfoWrapper, InfoRow, Column1, Column2, TextWrapper, TopLine, Heading, Subtitle, BtnWrap, ImgWrap, Img } from './InfoElements'
const Info = ({lightBg, id, imgStart, topLine, lightText, headline, darkText, description, buttonLabel, alt, img, primary, dark, dark2 }) => {
return (
<>
<InfoContainer lightBg={lightBg} id={id}>
<InfoWrapper>
<InfoRow imgStart={imgStart}>
<Column1>
<TextWrapper>
<TopLine>{topLine}</TopLine>
<Heading lightText={lightText}>{headline}</Heading>
<Subtitle darkText={darkText}>{description}</Subtitle>
<BtnWrap>
<Button to='home'
smooth={true}
duration={500}
spy={true}
exact='true'
offset={-80}
primary={primary ? 1 : 0}
dark={dark ? 1 : 0}
dark2={dark2 ? 1 : 0}
>{buttonLabel}
</Button>
</BtnWrap>
</TextWrapper>
</Column1>
<Column2>
<ImgWrap>
<Img src={img} alt={alt}/>
</ImgWrap>
</Column2>
</InfoRow>
</InfoWrapper>
</InfoContainer>
</>
)
}
export default Info
1) 컴포넌트부터 잡는다
2) (선수작업: 4-1부터) 각종 styledComponent를 가져온다
import { Button } from '../ButtonElements'
import { InfoContainer, InfoWrapper, InfoRow, Column1, Column2, TextWrapper, TopLine, Heading, Subtitle, BtnWrap, ImgWrap, Img } from './InfoElements'
3) props를 인자로 받아와 설정한다
const Info = ({lightBg, id, imgStart, topLine, lightText, headline, darkText, description, buttonLabel, alt, img, primary, dark, dark2 }) => {
return (
<>
<InfoContainer lightBg={lightBg} id={id}>
<InfoWrapper>
<InfoRow imgStart={imgStart}>
<Column1>
<TextWrapper>
<TopLine>{topLine}</TopLine>
<Heading lightText={lightText}>{headline}</Heading>
<Subtitle darkText={darkText}>{description}</Subtitle>
<BtnWrap>
<Button to='home'
smooth={true}
duration={500}
spy={true}
exact='true'
offset={-80}
primary={primary ? 1 : 0}
dark={dark ? 1 : 0}
dark2={dark2 ? 1 : 0}
>{buttonLabel}
</Button>
</BtnWrap>
</TextWrapper>
</Column1>
<Column2>
<ImgWrap>
<Img src={img} alt={alt}/>
</ImgWrap>
</Column2>
</InfoRow>
</InfoWrapper>
</InfoContainer>
</>
)
}
export default Info
-button은 react-scroll의 값을 설정한 것이다.
(src/pages/index.js)
import React, {useState} from 'react'
import Footer from '../components/Footer';
import Hero from '../components/Hero'
import Info from '../components/Info'
import { homeObjOne, homeObjTwo, homeObjThree} from '../components/Info/Data';
import Navbar from '../components/Navbar'
import Services from '../components/Services';
import Sidebar from '../components/SideBar'
const Home = () => {
const [isOpen, setIsOpen] = useState(false)
const toggle = () =>{
setIsOpen(!isOpen);
}
return (
<>
<Sidebar isOpen={isOpen} toggle={toggle} />
<Navbar toggle={toggle}/>
<Hero />
<Info {...homeObjOne}/>
<Info {...homeObjTwo}/>
<Services />
<Info {...homeObjThree}/>
<Footer />
</>
)
}
export default Home
1) 각종 컴포넌트를 넣는다
2) useState로 isOpen을 넣는다
3) toggle할 때마다 isOpen을 설정한다
4) Info의 props로 homeObjsOne을 가져온다
import styled from 'styled-components';
export const InfoContainer = styled.div`
color: #fff;
background: ${({lightBg}) => (lightBg ? '#f9f9f9' : '#010606')};
@media screen and (max-width: 768px) {
padding: 100px 0;
}
`
export const InfoWrapper = styled.div`
display: grid;
z-index: 1;
height: 860px;
width: 100%auto;
max-width: 1100px;
margin-right: auto;
margin-left: auto;
padding: 0 24px;
justify-content: center;
`
export const InfoRow = styled.div`
display: grid;
grid-auto-columns: minmax(auto, 1fr);
align-items: center;
grid-template-areas: ${({imgStart}) => (imgStart ? `'col2 col1'` : `'col1 col2'`)};
@media screen and (max-width: 768px) {
grid-template-areas: ${({imgStart}) => (imgStart ? `'col1' 'col2'` : `'col1 col1' 'col2 col2'`)}
}
`
export const Column1 = styled.div`
margin-bottom: 15px;
padding: 0 15px;
grid-area: col1;
`
export const Column2 = styled.div`
margin-bottom: 15px;
padding: 0 15px;
grid-area: col2;
`
export const TextWrapper = styled.div`
max-width: 540px;
padding-top: 0;
padding-bottom: 60px;
`
export const TopLine = styled.p`
color: #01bf71;
font-size: 16px;
line-height: 16px;
font-weight: 700;
letter-spacing: 1.4px;
text-transform: uppercase;
margin-bottom: 16px;
`
export const Heading = styled.h1`
margin-bottom: 24px;
font-size: 48px;
line-height: 1.1;
font-weight: 600px;
color: ${({lightText}) => (lightText ? '#f7f8fa' : '#010606')};
@media screen and (max-width: 480px) {
font-size: 32px;
}
`
export const Subtitle = styled.p`
max-width: 440px;
margin-bottom: 35px;
font-size: 18px;
line-height: 24px;
color: ${({darkText}) => (darkText ? '#010606' : '#fff')};
`
export const BtnWrap = styled.div`
display:flex;
justify-content: flex-start;
`;
export const ImgWrap = styled.div`
max-width: 555px;
height: 100%;
`;
export const Img = styled.img`
width: 100%;
margin: 0 0 10px 0;
padding-right: 0;
`;
1) infoWrapper
-grid를 적용한다
-width는 100%로, max width는 고정 픽셀로 제시한다
-height는 고정 픽셀로 제시한다
2) InfoRow
3) Column1, Column2
-2) 의 grid area다
4) TextWrapper
5) TopLine
6) Heading
7) Subtitle
8) BtnWrap
9) ImgWrap
-3(Column2)에 속함
-max-width: 고정 px로 정해놓는다. 그러면 사이트가 아무리 늘어나도 더 이상 안 커진다.
10) Img
-9에 속함
export const homeObjOne = {
id: 'about',
lightBg: false,
lightText: true,
lighttextDesc: true,
topLine: 'Premium Bank',
headline: 'Unlimited Transactions with zero fees',
description: 'Get access to our exclusive app that allows you to send unlimited transactions whitout getting charged any fees.',
buttonLabel: 'Get started',
imgStart: false,
img: '/images/svg-1.svg',
alt: 'car',
dark: true,
primary: true,
darkText: false
};
export const homeObjTwo = {
id: 'discover',
lightBg: true,
lightText: false,
lighttextDesc: false,
topLine: 'Unlimited Access',
headline: 'Login to your account at any time',
description: 'Get access to our exclusive app that allows you to send unlimited transactions whitout getting charged any fees.',
buttonLabel: 'Learn More',
imgStart: true,
img: '/images/svg-4.svg',
alt: 'Piggybanck',
dark: false,
primary: false,
darkText: true
};
export const homeObjThree = {
id: 'signup',
lightBg: true,
lightText: false,
lighttextDesc: false,
topLine: 'Premium Bank',
headline: 'Creating an account is extremely easy',
description: 'Get access to our exclusive app that allows you to send unlimited transactions whitout getting charged any fees.',
buttonLabel: 'Start Now',
imgStart: false,
img: '/images/svg-3.svg',
alt: 'car',
primary: false,
darkText: true
};
1) Data 파일을 작성한다
2) Undraw 사이트에 가서 사용할 파일을 다운받는다
3) 페이지에 가서 homeObjOne.. 등을 가져와 의 props로 넣는다(4-4)
4) 3-3(info/index.js)에 가서 props를 받아와 설정한다.
-스타일이 될 수도, 이미지 파일이 될 수도, 다양하다.