import { motion } from "framer-motion";
import { Link, useRouteMatch } from "react-router-dom";
import { useRecoilState } from "recoil";
import styled from "styled-components";
import { booleanState } from "../atoms";
const Inner = styled.div`
display: flex;
flex-direction: column;
gap: 32px;
align-items: center;
justify-content: center;
padding: 20px 0 28px;
border-bottom: 1px solid ${(props) => props.theme.bgColor.gray.fixth};
`;
const Row = styled.div`
position: relative;
width: 100%;
`;
const Logo = styled.div`
color: ${(props) =>props.theme.point.lavender};
font: 20px 'Righteous';
text-align: center;
`;
const Em = styled.span`
display: inline-block;
padding-left: 16px;
color: ${(props) => props.theme.point.purple};
font-size: 38px;
text-align: center;
`;
const Items = styled.ul`
display: flex;
align-items: center;
justify-content: center;
gap: 12px 38px;
`;
const Item = styled.li`
position: relative;
color: ${(props) => props.theme.textColor.gray.second};
font-size: 28px;
font-weight: 700;
line-height: 31px;
a {
&.on {
color: ${props=>props.theme.point.yellow};
}
}
`;
const Point = styled(motion.span)`
position: absolute;
width: 16px;
height: 5px;
top: -8px;
left: 0;
right: 0;
margin: 0 auto;
border-radius: 7px;
background-color: ${props=>props.theme.point.yellow};
`;
function Header(){
// Link
const homeMatch = useRouteMatch("/");
const worksMatch = useRouteMatch("/works");
const infoMatch = useRouteMatch("/info");
return (
<Inner>
<Row>
<Logo>
<Em>LOGO</Em>
</Logo>
</Row>
<Row>
<Items>
<Item>
<Link to="/" className={homeMatch?.isExact ? "on": ""}>
Intro
{homeMatch?.isExact === true && <Point layoutId="point"/>}
</Link>
</Item>
<Item>
<Link to="/works" className={worksMatch? "on": ""}>
Works
{worksMatch && <Point layoutId="point"/>}
</Link>
</Item>
<Item>
<Link to="/info" className={infoMatch? "on": ""}>
Info
{infoMatch && <Point layoutId="point"/>}
</Link>
</Item>
</Items>
</Row>
</Inner>
);
}
export default Header;
import {BrowserRouter as Router, Switch, Route} from "react-router-dom";
import Info from "./Routes/Info";
import Works from "./Routes/Works";
import Header from "./Components/Header";
import Intro from "./Routes/Intro";
import { booleanState } from "./atoms";
import { ThemeProvider, createGlobalStyle } from "styled-components";
import { useRecoilValue } from "recoil";
import { darkTheme, lightTheme } from "./theme";
const GlobalStyle = createGlobalStyle`
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, menu, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
main, menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, main, menu, nav, section {
display: block;
}
/* HTML5 hidden-attribute fix for newer browsers */
*[hidden] {
display: none;
}
menu, ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
* {
box-sizing: border-box;
transition: all 0.2s ease-in;
}
body {
font-weight: 300;
font-family: 'Noto Sans KR', 'Righteous';
color:${(props) => props.theme.textColor.gray.third};
line-height: 1.5;
background-color: ${(props) => props.theme.bgColor.gray.second};
}
a {
text-decoration:none;
color:inherit;
}
`;
function App() {
const themeSate = useRecoilValue(booleanState);
return (
<ThemeProvider theme={themeSate ? darkTheme : lightTheme}>
<GlobalStyle />
<Router>
<Header />
<Switch>
<Route path="/works">
<Works />
</Route>
<Route path="/info">
<Info />
</Route>
<Route path="/">
<Intro />
</Route>
</Switch>
</Router>
</ThemeProvider>
);
}
export default App;
9. 로컬 실행 잘 되나 확인
10. 백엔드 환경 구축 (다음 편에서 계속............)