mirror of
https://github.com/Stone-Red-Code/website.git
synced 2026-09-08 23:44:09 +02:00
Merge pull request #80 from the-programmers-hangout/feat-responsive-resources
feat: responsive resources
This commit is contained in:
@@ -66,4 +66,8 @@ export const MarkdownWrapper = styled.div`
|
|||||||
h6 {
|
h6 {
|
||||||
${modularScaleCSS(1)};
|
${modularScaleCSS(1)};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pre[class*="language-"] {
|
||||||
|
overflow-x: scroll;
|
||||||
|
}
|
||||||
`
|
`
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import React from "react"
|
||||||
|
import * as SC from "./styles"
|
||||||
|
|
||||||
|
interface IMobileHeaderProps {
|
||||||
|
openMenu: () => void
|
||||||
|
}
|
||||||
|
|
||||||
|
export function MobileHeader({ openMenu }: IMobileHeaderProps) {
|
||||||
|
return (
|
||||||
|
<SC.MobileHeaderWrapper>
|
||||||
|
<SC.LogoWrapper>
|
||||||
|
<SC.StyledLogo />
|
||||||
|
</SC.LogoWrapper>
|
||||||
|
Resources
|
||||||
|
<SC.Burger onClick={openMenu} />
|
||||||
|
</SC.MobileHeaderWrapper>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
import styled from "styled-components"
|
||||||
|
import { fontFamily } from "../../design/typography"
|
||||||
|
import Logo from "../../images/tph-logo.svg"
|
||||||
|
|
||||||
|
export const MobileHeaderWrapper = styled.div`
|
||||||
|
z-index: 50;
|
||||||
|
background: rgba(255, 255, 255, 0.8);
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
padding: 16px 32px;
|
||||||
|
display: none;
|
||||||
|
align-items: center;
|
||||||
|
font-weight: 700;
|
||||||
|
font-family: ${fontFamily.header};
|
||||||
|
font-size: 22px;
|
||||||
|
|
||||||
|
@media screen and (max-width: 767px) {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
export const LogoWrapper = styled.div`
|
||||||
|
width: 35px;
|
||||||
|
height: 35px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
background: #222;
|
||||||
|
border-radius: 7px;
|
||||||
|
margin-right: 8px;
|
||||||
|
`
|
||||||
|
|
||||||
|
export const StyledLogo = styled(Logo)`
|
||||||
|
height: 25px;
|
||||||
|
`
|
||||||
|
|
||||||
|
export const Burger = styled.div`
|
||||||
|
margin-left: auto;
|
||||||
|
width: 16px;
|
||||||
|
height: 9px;
|
||||||
|
padding: 8px;
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&::before,
|
||||||
|
&::after {
|
||||||
|
position: absolute;
|
||||||
|
content: "";
|
||||||
|
height: 2px;
|
||||||
|
width: 16px;
|
||||||
|
background: #222;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
bottom: 8px;
|
||||||
|
}
|
||||||
|
`
|
||||||
@@ -4,6 +4,11 @@ import styled from "styled-components"
|
|||||||
export const ResourceBreadcrumbWrapper = styled.div`
|
export const ResourceBreadcrumbWrapper = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
|
|
||||||
|
@media screen and (max-width: 767px) {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
export const LinkWrapper = styled.div`
|
export const LinkWrapper = styled.div`
|
||||||
|
|||||||
@@ -65,9 +65,9 @@ export function ResourceHeader({
|
|||||||
<SC.Title>{title}</SC.Title>
|
<SC.Title>{title}</SC.Title>
|
||||||
|
|
||||||
<SC.Top>
|
<SC.Top>
|
||||||
<StackedAvatars authors={authors} />
|
|
||||||
<SC.Meta>
|
<SC.Meta>
|
||||||
{authors.length} contributor{authors.lenght > 1 && "s"}
|
<StackedAvatars authors={authors} /> {authors.length} contributor
|
||||||
|
{authors.lenght > 1 && "s"}
|
||||||
</SC.Meta>
|
</SC.Meta>
|
||||||
<SC.Meta>{dateToHuman}</SC.Meta>
|
<SC.Meta>{dateToHuman}</SC.Meta>
|
||||||
<SC.Meta>
|
<SC.Meta>
|
||||||
|
|||||||
@@ -11,6 +11,11 @@ export const ResourceHeaderWrapper = styled.div`
|
|||||||
export const Top = styled.div`
|
export const Top = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
|
@media screen and (max-width: 767px) {
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
export const Title = styled.h1`
|
export const Title = styled.h1`
|
||||||
@@ -22,10 +27,23 @@ export const Title = styled.h1`
|
|||||||
`
|
`
|
||||||
|
|
||||||
export const Meta = styled.div`
|
export const Meta = styled.div`
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
& + &::before {
|
& + &::before {
|
||||||
content: "•";
|
content: "•";
|
||||||
margin: 0 8px;
|
margin: 0 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 767px) {
|
||||||
|
& + & {
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
& + &::before {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
const ExtraLinks = styled.div`
|
const ExtraLinks = styled.div`
|
||||||
|
|||||||
@@ -5,23 +5,39 @@
|
|||||||
* See: https://www.gatsbyjs.org/docs/use-static-query/
|
* See: https://www.gatsbyjs.org/docs/use-static-query/
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { PropsWithChildren } from "react"
|
import React, { PropsWithChildren, useState } from "react"
|
||||||
|
|
||||||
import { GlobalStyles } from "../../globalStyles"
|
import { GlobalStyles } from "../../globalStyles"
|
||||||
import { SidebarProvider } from "../../SidebarProvider"
|
import { SidebarProvider } from "../../SidebarProvider"
|
||||||
|
import { MobileHeader } from "../MobileHeader"
|
||||||
import { ResourcesSidebar } from "../ResourcesSidebar"
|
import { ResourcesSidebar } from "../ResourcesSidebar"
|
||||||
import * as SC from "./styles"
|
import * as SC from "./styles"
|
||||||
|
|
||||||
export function ResourcesLayout({ children }: PropsWithChildren<{}>) {
|
export function ResourcesLayout({ children }: PropsWithChildren<{}>) {
|
||||||
|
const [activeMobileMenu, setActiveMobileMenu] = useState(false)
|
||||||
|
|
||||||
|
function openMenu() {
|
||||||
|
setActiveMobileMenu(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeMenu() {
|
||||||
|
setActiveMobileMenu(false)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SidebarProvider>
|
<SidebarProvider>
|
||||||
<GlobalStyles />
|
<GlobalStyles />
|
||||||
<SC.Main>
|
<SC.Main>
|
||||||
<ResourcesSidebar />
|
<MobileHeader openMenu={openMenu} />
|
||||||
|
<ResourcesSidebar className={activeMobileMenu ? "is-open" : ""} />
|
||||||
<SC.MainContent>
|
<SC.MainContent>
|
||||||
<SC.Container>{children}</SC.Container>
|
<SC.Container>{children}</SC.Container>
|
||||||
</SC.MainContent>
|
</SC.MainContent>
|
||||||
</SC.Main>
|
</SC.Main>
|
||||||
|
<SC.Overlay
|
||||||
|
className={activeMobileMenu ? "is-open" : ""}
|
||||||
|
onClick={closeMenu}
|
||||||
|
/>
|
||||||
</SidebarProvider>
|
</SidebarProvider>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,9 +6,35 @@ export const Main = styled.div`
|
|||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
`
|
`
|
||||||
|
|
||||||
|
export const Overlay = styled.div`
|
||||||
|
z-index: 99;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
transition: background-color 0.3s;
|
||||||
|
background-color: rgba(0, 0, 0, 0);
|
||||||
|
pointer-events: none;
|
||||||
|
|
||||||
|
@media screen and (min-width: 768px) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-open {
|
||||||
|
pointer-events: auto;
|
||||||
|
background-color: rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
export const MainContent = styled.main`
|
export const MainContent = styled.main`
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
margin-top: 128px;
|
margin-top: 128px;
|
||||||
|
width: calc(100% - 320px);
|
||||||
|
|
||||||
|
@media screen and (max-width: 767px) {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
& > :first-child {
|
& > :first-child {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
@@ -21,5 +47,7 @@ export const MainContent = styled.main`
|
|||||||
|
|
||||||
export const Container = styled.div`
|
export const Container = styled.div`
|
||||||
width: 650px;
|
width: 650px;
|
||||||
|
max-width: calc(100% - 64px);
|
||||||
|
padding: 0 32px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
`
|
`
|
||||||
|
|||||||
@@ -117,12 +117,12 @@ function MenuItem({ children, to }: PropsWithChildren<{ to: string }>) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ResourcesSidebar() {
|
export function ResourcesSidebar(props: React.HTMLAttributes<HTMLDivElement>) {
|
||||||
const resources = useStaticQuery<IAllResourcesQuery>(ALL_RESOURCES)
|
const resources = useStaticQuery<IAllResourcesQuery>(ALL_RESOURCES)
|
||||||
const tree = useBuildTree(resources)
|
const tree = useBuildTree(resources)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SC.ResourcesSidebarWrapper>
|
<SC.ResourcesSidebarWrapper {...props}>
|
||||||
<Link to="/">
|
<Link to="/">
|
||||||
<Banner />
|
<Banner />
|
||||||
</Link>
|
</Link>
|
||||||
|
|||||||
@@ -6,6 +6,23 @@ export const ResourcesSidebarWrapper = styled.div`
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
flex: 0 0 320px;
|
flex: 0 0 320px;
|
||||||
background: #f9f9f9;
|
background: #f9f9f9;
|
||||||
|
|
||||||
|
@media screen and (max-width: 767px) {
|
||||||
|
z-index: 100;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
/* TODO: maybe find a less "awkward" way to animate this */
|
||||||
|
left: calc(-100% - 100px);
|
||||||
|
right: calc(100% - 0px);
|
||||||
|
transition: left 0.3s, right 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.is-open {
|
||||||
|
left: 0;
|
||||||
|
right: 100px;
|
||||||
|
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
export const Children = styled.div`
|
export const Children = styled.div`
|
||||||
|
|||||||
Reference in New Issue
Block a user