moving from hexo theme to my own react design
This commit is contained in:
parent
7ff3176072
commit
379c1c60d9
96 changed files with 1990 additions and 50291 deletions
66
source/src/components/Footer.tsx
Normal file
66
source/src/components/Footer.tsx
Normal file
|
@ -0,0 +1,66 @@
|
|||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
|
||||
import { faGithub } from "@fortawesome/free-brands-svg-icons"
|
||||
import styled from "styled-components"
|
||||
import theme from "styled-theming"
|
||||
import { HashRouter as Router, Link } from "react-router-dom"
|
||||
|
||||
const StyledFooter = styled.footer`
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 1px; /* footer goes outside the page by 1 px for some reason */
|
||||
padding: 50px 10px;
|
||||
background-color: white;
|
||||
background-color: ${theme("mode", {
|
||||
light: "white",
|
||||
dark: "black",
|
||||
})};
|
||||
color: ${theme("mode", {
|
||||
light: "black",
|
||||
dark: "white",
|
||||
})};
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.logo {
|
||||
color: gray;
|
||||
}
|
||||
`
|
||||
|
||||
const StyledLink = styled.a`
|
||||
width: 30px;
|
||||
font-size: 2rem;
|
||||
color: ${theme("mode", {
|
||||
light: "lightgrey",
|
||||
dark: "grey",
|
||||
})};
|
||||
|
||||
&:hover {
|
||||
color: ${theme("mode", {
|
||||
light: "black",
|
||||
dark: "white",
|
||||
})};
|
||||
}
|
||||
`
|
||||
|
||||
function Footer() {
|
||||
return (
|
||||
<StyledFooter>
|
||||
<div className="logo">
|
||||
Copyright © <strong>develo</strong>pomp
|
||||
</div>
|
||||
|
||||
<Router className="icons">
|
||||
<StyledLink
|
||||
href="https://github.com/developomp/developomp-site"
|
||||
target="_blank"
|
||||
>
|
||||
<FontAwesomeIcon icon={faGithub} />
|
||||
</StyledLink>
|
||||
</Router>
|
||||
</StyledFooter>
|
||||
)
|
||||
}
|
||||
|
||||
export default Footer
|
100
source/src/components/Navbar.tsx
Normal file
100
source/src/components/Navbar.tsx
Normal file
|
@ -0,0 +1,100 @@
|
|||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
|
||||
import { faGithub } from "@fortawesome/free-brands-svg-icons"
|
||||
import styled, { ThemeConsumer } from "styled-components"
|
||||
import theme from "styled-theming"
|
||||
import ReactTooltip from "react-tooltip"
|
||||
import NavbarData from "../data/NavbarData"
|
||||
import theming from "../theming"
|
||||
|
||||
import { Link } from "react-router-dom"
|
||||
import SearchBox from "./SearchBox"
|
||||
import Sidebar from "./Sidebar"
|
||||
import ThemeToggleButton from "./ThemeToggleButton"
|
||||
import { faLanguage } from "@fortawesome/free-solid-svg-icons"
|
||||
|
||||
const StyledNav = styled.nav`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 2rem;
|
||||
margin: 0;
|
||||
padding: 1rem;
|
||||
background-color: ${theme("mode", {
|
||||
light: theming.light.backgroundColor0,
|
||||
dark: theming.dark.backgroundColor0,
|
||||
})};
|
||||
color: ${theme("mode", {
|
||||
light: theming.light.color0,
|
||||
dark: theming.dark.color0,
|
||||
})};
|
||||
box-shadow: 0 4px 10px rgb(0 0 0 / 5%);
|
||||
|
||||
.right {
|
||||
margin-left: auto;
|
||||
}
|
||||
`
|
||||
|
||||
const StyledNavLinks = styled.div`
|
||||
@media only screen and (max-width: ${theming.size.screen_size1}) {
|
||||
display: none;
|
||||
}
|
||||
`
|
||||
|
||||
const StyledImg = styled.img`
|
||||
height: 2rem;
|
||||
margin: 1rem;
|
||||
`
|
||||
|
||||
const StyledLink = styled(Link)`
|
||||
${theming.styles.navbarButtonStyle}
|
||||
`
|
||||
|
||||
const StyledALink = styled.a`
|
||||
${theming.styles.navbarButtonStyle}
|
||||
`
|
||||
|
||||
function Navbar() {
|
||||
return (
|
||||
<StyledNav>
|
||||
<Link to="/">
|
||||
<StyledImg
|
||||
src={process.env.PUBLIC_URL + "/icon/icon_circle.svg"}
|
||||
/>
|
||||
</Link>
|
||||
<StyledNavLinks>
|
||||
{NavbarData.map((item, index) => {
|
||||
return (
|
||||
<StyledLink key={index} to={item.path}>
|
||||
{item.title}
|
||||
</StyledLink>
|
||||
)
|
||||
})}
|
||||
</StyledNavLinks>
|
||||
|
||||
<ThemeToggleButton />
|
||||
|
||||
<StyledALink data-tip data-for="language">
|
||||
<FontAwesomeIcon icon={faLanguage} />
|
||||
</StyledALink>
|
||||
<ReactTooltip id="language" type="dark" effect="solid">
|
||||
<span>Change to Korean/English</span>
|
||||
</ReactTooltip>
|
||||
|
||||
<StyledALink
|
||||
data-tip
|
||||
data-for="github"
|
||||
href="https://github.com/developomp/developomp-site"
|
||||
target="_blank"
|
||||
>
|
||||
<FontAwesomeIcon icon={faGithub} />
|
||||
</StyledALink>
|
||||
<ReactTooltip id="github" type="dark" effect="solid">
|
||||
<span>View source code</span>
|
||||
</ReactTooltip>
|
||||
|
||||
<SearchBox />
|
||||
<Sidebar />
|
||||
</StyledNav>
|
||||
)
|
||||
}
|
||||
|
||||
export default Navbar
|
51
source/src/components/SearchBox.tsx
Normal file
51
source/src/components/SearchBox.tsx
Normal file
|
@ -0,0 +1,51 @@
|
|||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
|
||||
import { faSearch } from "@fortawesome/free-solid-svg-icons"
|
||||
import styled, { ThemeConsumer, css } from "styled-components"
|
||||
import theme from "styled-theming"
|
||||
|
||||
const StyledSearchBoxContainer = styled.div`
|
||||
display: flex;
|
||||
justify-content: left;
|
||||
align-items: center;
|
||||
background-color: ${theme("mode", {
|
||||
light: "white",
|
||||
dark: "#202225",
|
||||
})};
|
||||
color: ${theme("mode", {
|
||||
light: "black",
|
||||
dark: "#CFD0D0",
|
||||
})};
|
||||
|
||||
&:hover {
|
||||
background-color: ${theme("mode", {
|
||||
light: "whitesmoke",
|
||||
dark: "#36393F",
|
||||
})};
|
||||
}
|
||||
`
|
||||
|
||||
const StyledSearchBox = styled.input`
|
||||
width: 80%;
|
||||
border: none;
|
||||
border-right: 1rem;
|
||||
outline: none;
|
||||
padding: 10px 10px;
|
||||
text-decoration: none;
|
||||
background-color: inherit;
|
||||
color: inherit;
|
||||
`
|
||||
|
||||
const StyledSearchButton = styled(FontAwesomeIcon)`
|
||||
cursor: pointer;
|
||||
`
|
||||
|
||||
function Navbar() {
|
||||
return (
|
||||
<StyledSearchBoxContainer>
|
||||
<StyledSearchBox type="text" name="search" placeholder="Search" />
|
||||
<StyledSearchButton icon={faSearch} />
|
||||
</StyledSearchBoxContainer>
|
||||
)
|
||||
}
|
||||
|
||||
export default Navbar
|
124
source/src/components/Sidebar.tsx
Normal file
124
source/src/components/Sidebar.tsx
Normal file
|
@ -0,0 +1,124 @@
|
|||
import { useEffect, useState } from "react"
|
||||
import styled, { css } from "styled-components"
|
||||
import NavbarData from "../data/NavbarData"
|
||||
import theme from "styled-theming"
|
||||
import ReactTooltip from "react-tooltip"
|
||||
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
|
||||
import { faEllipsisV, faTimes } from "@fortawesome/free-solid-svg-icons"
|
||||
|
||||
import theming from "../theming"
|
||||
import SubMenu from "./SubMenu"
|
||||
|
||||
interface StateProps {
|
||||
isSidebarOpen: boolean
|
||||
}
|
||||
|
||||
const CommonSidebarToggleButtonStyle = css`
|
||||
${theming.styles.navbarButtonStyle}
|
||||
font-size: "1.5rem";
|
||||
width: 1.5rem;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
margin: 0.1rem;
|
||||
@media only screen and (min-width: ${theming.size.screen_size1}) {
|
||||
display: none;
|
||||
}
|
||||
`
|
||||
|
||||
const StyledToggleSidebarButton = styled.div`
|
||||
${CommonSidebarToggleButtonStyle}
|
||||
`
|
||||
|
||||
const StyledToggleSidebarButton2 = styled.div`
|
||||
${CommonSidebarToggleButtonStyle}
|
||||
border-radius: 0;
|
||||
margin: auto;
|
||||
width: 90%;
|
||||
height: 2rem;
|
||||
font-size: 1.1rem;
|
||||
`
|
||||
|
||||
const StyledOverlay = styled.div<StateProps>`
|
||||
display: ${(props) => (props.isSidebarOpen ? "block" : "none")};
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 20;
|
||||
transition-property: opacity;
|
||||
background-color: rgba(0, 0, 0, 25%);
|
||||
|
||||
* {
|
||||
overflow: scroll;
|
||||
}
|
||||
`
|
||||
|
||||
const SidebarNav = styled.nav<StateProps>`
|
||||
width: 250px;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: ${(props) => (props.isSidebarOpen ? "0" : "-100%")};
|
||||
transition: 350ms;
|
||||
z-index: 30;
|
||||
overflow-x: hidden;
|
||||
overflow-y: scroll;
|
||||
background-color: ${theme("mode", {
|
||||
light: theming.light.backgroundColor0,
|
||||
dark: theming.dark.backgroundColor0,
|
||||
})};
|
||||
color: ${theme("mode", {
|
||||
light: theming.light.color0,
|
||||
dark: theming.dark.color0,
|
||||
})};
|
||||
`
|
||||
|
||||
const SidebarWrap = styled.div`
|
||||
width: 100%;
|
||||
`
|
||||
|
||||
const Sidebar = () => {
|
||||
const [isSidebarOpen, setSidebar] = useState(false)
|
||||
|
||||
function toggleSidebar() {
|
||||
setSidebar(!isSidebarOpen)
|
||||
document.body.style.overflow = isSidebarOpen ? "scroll" : "hidden"
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<StyledOverlay
|
||||
isSidebarOpen={isSidebarOpen}
|
||||
onClick={toggleSidebar}
|
||||
/>
|
||||
|
||||
<StyledToggleSidebarButton
|
||||
data-tip
|
||||
data-for="sidebar"
|
||||
onClick={toggleSidebar}
|
||||
>
|
||||
<FontAwesomeIcon icon={faEllipsisV}></FontAwesomeIcon>
|
||||
<ReactTooltip id="sidebar" type="dark" effect="solid">
|
||||
<span>open sidebar</span>
|
||||
</ReactTooltip>
|
||||
</StyledToggleSidebarButton>
|
||||
|
||||
<SidebarNav isSidebarOpen={isSidebarOpen}>
|
||||
<SidebarWrap>
|
||||
<StyledToggleSidebarButton2 onClick={toggleSidebar}>
|
||||
<FontAwesomeIcon icon={faTimes}></FontAwesomeIcon> Close
|
||||
</StyledToggleSidebarButton2>
|
||||
{NavbarData.map((item, index) => {
|
||||
return <SubMenu item={item} key={index} />
|
||||
})}
|
||||
</SidebarWrap>
|
||||
</SidebarNav>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default Sidebar
|
74
source/src/components/SubMenu.tsx
Normal file
74
source/src/components/SubMenu.tsx
Normal file
|
@ -0,0 +1,74 @@
|
|||
import { useState } from "react"
|
||||
import { Link } from "react-router-dom"
|
||||
import styled from "styled-components"
|
||||
import theming from "../theming"
|
||||
|
||||
const SidebarLink = styled(Link)`
|
||||
${theming.styles.navbarButtonStyle};
|
||||
display: flex;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
border-radius: 0;
|
||||
justify-content: space-between;
|
||||
height: 2rem;
|
||||
align-items: center;
|
||||
padding: 20px;
|
||||
list-style: none;
|
||||
`
|
||||
|
||||
const SidebarLabel = styled.span`
|
||||
margin-left: 16px;
|
||||
`
|
||||
|
||||
const DropdownLink = styled(Link)`
|
||||
background: #414757;
|
||||
height: 60px;
|
||||
padding-left: 3rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
text-decoration: none;
|
||||
color: #f5f5f5;
|
||||
font-size: 18px;
|
||||
|
||||
&:hover {
|
||||
background: #632ce4;
|
||||
cursor: pointer;
|
||||
}
|
||||
`
|
||||
|
||||
function SubMenu({ item }) {
|
||||
const [isSubNavOpen, setSubNav] = useState(false)
|
||||
|
||||
const showSubNav = () => setSubNav(!isSubNavOpen)
|
||||
|
||||
return (
|
||||
<>
|
||||
<SidebarLink to={item.path} onClick={item.subNav && showSubNav}>
|
||||
<div>
|
||||
{item.icon}
|
||||
<SidebarLabel>{item.title}</SidebarLabel>
|
||||
</div>
|
||||
<div>
|
||||
{item.subNav && isSubNavOpen
|
||||
? item.iconOpened
|
||||
: item.subNav
|
||||
? item.iconClosed
|
||||
: null}
|
||||
</div>
|
||||
</SidebarLink>
|
||||
|
||||
{/* not used as of the moment */}
|
||||
{isSubNavOpen &&
|
||||
item.subNav.map((item, index) => {
|
||||
return (
|
||||
<DropdownLink to={item.path} key={index}>
|
||||
{item.icon}
|
||||
<SidebarLabel>{item.title}</SidebarLabel>
|
||||
</DropdownLink>
|
||||
)
|
||||
})}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default SubMenu
|
50
source/src/components/ThemeToggleButton.tsx
Normal file
50
source/src/components/ThemeToggleButton.tsx
Normal file
|
@ -0,0 +1,50 @@
|
|||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
|
||||
import { faAdjust } from "@fortawesome/free-solid-svg-icons"
|
||||
import styled, { ThemeConsumer } from "styled-components"
|
||||
import theme from "styled-theming"
|
||||
|
||||
import ReactTooltip from "react-tooltip"
|
||||
|
||||
import theming from "../theming"
|
||||
|
||||
const StyledThemeButton = styled.div`
|
||||
${theming.styles.navbarButtonStyle}
|
||||
transition: transform 0.2s linear;
|
||||
${theme("mode", {
|
||||
light: "",
|
||||
dark: "transform: scaleX(-1);\
|
||||
-moz-transform: scaleX(-1);\
|
||||
-webkit-transform: scaleX(-1);\
|
||||
-ms-transform: scaleX(-1);",
|
||||
})};
|
||||
`
|
||||
|
||||
function Navbar() {
|
||||
return (
|
||||
<ThemeConsumer>
|
||||
{(_theme) => (
|
||||
<>
|
||||
<StyledThemeButton
|
||||
data-tip
|
||||
data-for="theme"
|
||||
className="right"
|
||||
onClick={(_: any) =>
|
||||
_theme.setTheme(
|
||||
_theme.mode === "dark"
|
||||
? { ..._theme, mode: "light" }
|
||||
: { ..._theme, mode: "dark" }
|
||||
)
|
||||
}
|
||||
>
|
||||
<FontAwesomeIcon icon={faAdjust} />
|
||||
</StyledThemeButton>
|
||||
<ReactTooltip id="theme" type="dark" effect="solid">
|
||||
<span>Change theme</span>
|
||||
</ReactTooltip>
|
||||
</>
|
||||
)}
|
||||
</ThemeConsumer>
|
||||
)
|
||||
}
|
||||
|
||||
export default Navbar
|
Loading…
Add table
Add a link
Reference in a new issue