header work WIP
This commit is contained in:
parent
b2fad77434
commit
6d2090eea9
@ -26,6 +26,13 @@ export const textSizes = {
|
||||
hg: 200,
|
||||
}
|
||||
|
||||
export const screenSizes = {
|
||||
xs: 670,
|
||||
sm: 800,
|
||||
md: 1000,
|
||||
lg: 1500,
|
||||
}
|
||||
|
||||
export const defaultTheme = {
|
||||
background: colours.midnightDarker, foreground: colours.rose, highlight: colours.highlight
|
||||
}
|
||||
|
@ -1,36 +1,66 @@
|
||||
import { h } from 'preact'
|
||||
import { Link as ReactLink } from 'react-router-dom'
|
||||
import { RightBox, StyledRow as Row } from './styles'
|
||||
import { RightBox, StyledRow as Row, Modal } from './styles'
|
||||
import { ImageLogo } from '../Logo'
|
||||
import { useWindowSize } from '../../hooks/dom'
|
||||
import Link from '../Link'
|
||||
import { Span } from '../Text'
|
||||
import CrossSvg from '../Svg/Cross'
|
||||
|
||||
import navigation from '../../data/navigation'
|
||||
import { colours, textSizes } from '../../assets/theme'
|
||||
import { colours, screenSizes, textSizes } from '../../assets/theme'
|
||||
import { useToggle } from '../../hooks/utility'
|
||||
|
||||
const Navigation = ({ theme = {}, lang = 'en' }) => (
|
||||
<RightBox as="nav">
|
||||
{navigation[lang].map(navItem => <Link navLink to={navItem.to} href={navItem.href} textProps={{
|
||||
size: textSizes.xl, colour: theme.foreground || colours.rose
|
||||
}}>{navItem.label}</Link>)}
|
||||
</RightBox>
|
||||
)
|
||||
const Navigation = ({ theme = {}, lang = 'en', headerTheme }) => navigation[lang].map(navItem => (
|
||||
<Link
|
||||
navLink
|
||||
to={navItem.to}
|
||||
href={navItem.href}
|
||||
textProps={{
|
||||
size: textSizes.xl,
|
||||
colour: headerTheme.foreground || theme.foreground || colours.rose
|
||||
}}>
|
||||
{navItem.label}
|
||||
</Link>
|
||||
))
|
||||
|
||||
|
||||
const BigHeader = ({ theme = {}, lang = 'en', ...rest }) => (
|
||||
<Row theme={theme} align="center" justify="space-between" {...rest}>
|
||||
const NavigationModal = ({ theme = {}, lang = 'en', headerTheme, toggleMenuOpen, ...rest }) => (
|
||||
<Modal theme={theme} {...rest}>
|
||||
<ReactLink to="/">
|
||||
<ImageLogo />
|
||||
</ReactLink>
|
||||
<Navigation theme={theme} lang={lang} {...rest} />
|
||||
<CrossSvg size={32} colour={theme.foreground} onClick={toggleMenuOpen} />
|
||||
<div>
|
||||
<Navigation theme={theme} lang={lang} headerTheme={theme} {...rest} />
|
||||
</div>
|
||||
</Modal>
|
||||
)
|
||||
|
||||
const FullHeader = ({ theme = {}, headerTheme = {}, lang = 'en', miniHeader, isMobile, toggleMenuOpen, ...rest }) => (
|
||||
<Row theme={headerTheme} align="center" justify="space-between" miniHeader={miniHeader} {...rest}>
|
||||
{!miniHeader ? <ReactLink to="/">
|
||||
<ImageLogo />
|
||||
</ReactLink> : null}
|
||||
{!isMobile ? (
|
||||
<RightBox as="nav">
|
||||
<Navigation theme={theme} lang={lang} headerTheme={headerTheme} {...rest} />
|
||||
</RightBox>
|
||||
) : <Span onClick={toggleMenuOpen} size={textSizes.xl} colour={headerTheme.foreground || theme.foreground || colours.rose} fontFamily="Lunchtype24"
|
||||
>Menu</Span>}
|
||||
</Row>
|
||||
)
|
||||
|
||||
const MiniHeader = ({ theme = {}, lang = 'en', ...rest }) => (
|
||||
<Row theme={theme} align="center" justify="space-between" miniHeader {...rest}>
|
||||
<Navigation theme={theme} lang={lang} {...rest} />
|
||||
</Row>
|
||||
)
|
||||
|
||||
const Header = ({ miniHeader, ...rest }) => miniHeader ? <MiniHeader {...rest} /> : <BigHeader {...rest} />
|
||||
|
||||
const Header = ({ miniHeader, theme, ...rest }) => {
|
||||
const headerTheme = { foreground: theme.background, background: 'transparent', }
|
||||
const { width: screenWidth } = useWindowSize()
|
||||
const [menuOpen, toggleMenuOpen] = useToggle(false)
|
||||
const isMobile = screenWidth < screenSizes.lg
|
||||
|
||||
if (menuOpen) return <NavigationModal toggleMenuOpen={toggleMenuOpen} theme={theme} headerTheme={headerTheme} {...rest} />
|
||||
|
||||
return <FullHeader toggleMenuOpen={toggleMenuOpen} menuOpen={menuOpen} miniHeader={miniHeader} isMobile={isMobile} theme={theme} headerTheme={headerTheme} {...rest} />
|
||||
}
|
||||
|
||||
export default Header
|
||||
|
@ -1,5 +1,7 @@
|
||||
import styled from 'styled-components'
|
||||
import { screenSizes } from '../../assets/theme'
|
||||
import { Row } from '../Flex'
|
||||
import CrossSvg from '../Svg/Cross'
|
||||
|
||||
|
||||
export const StyledRow = styled(Row)`
|
||||
@ -19,12 +21,56 @@ export const StyledRow = styled(Row)`
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
opacity: 0.5;
|
||||
|
||||
a, span {
|
||||
margin-right: 2em;
|
||||
cursor: pointer;
|
||||
|
||||
@media screen and (max-width: ${screenSizes.md}px) {
|
||||
margin-right: 1em;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
`
|
||||
export const RightBox = styled(Row)`
|
||||
a {
|
||||
margin-right: 4em;
|
||||
`
|
||||
|
||||
export const Modal = styled.div`
|
||||
z-index: 100;
|
||||
background-color: ${({ theme }) => theme.background};
|
||||
color: ${({ theme }) => theme.foreground};
|
||||
position: fixed;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
pointer-events: all;
|
||||
|
||||
|
||||
img {
|
||||
max-height: 80px;
|
||||
mix-blend-mode: exclusion;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
div {
|
||||
padding: 3em;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
div a {
|
||||
margin-bottom: 1em;
|
||||
font-size: 6vh;
|
||||
display: inline-block;
|
||||
line-height: 0.8;
|
||||
}
|
||||
`
|
||||
export const PositionedCross = styled(CrossSvg)`
|
||||
position: fixed;
|
||||
right: 1em;
|
||||
top: 1em;
|
||||
`
|
@ -11,8 +11,6 @@ const Link = ({ children, to, activeOnlyWhenExact = true, href, textProps: { col
|
||||
exact: activeOnlyWhenExact
|
||||
})
|
||||
|
||||
console.log({ colour })
|
||||
|
||||
return href ? <A href={href} colour={colour} size={size} fontFamily={navLink ? 'Lunchtype24' : null} {...rest}>{children}</A> : (
|
||||
<A as="span" colour={colour} size={size} {...rest}>
|
||||
<RRLink to={to} $navLink={navLink} $colour={colour} $selected={match && navLink}>{children}</RRLink>
|
||||
|
@ -1,5 +1,8 @@
|
||||
export const slugify = (title) => {
|
||||
let str = title.replace(/^\s+|\s+$/g, '') // trim
|
||||
let str = title ? title.replace(/^\s+|\s+$/g, '') : null // trim
|
||||
|
||||
if (!str) return title;
|
||||
|
||||
str = str.toLowerCase()
|
||||
|
||||
// remove accents, swap ñ for n, etc
|
||||
@ -22,11 +25,11 @@ export const capitaliseFirstLetter = word =>
|
||||
word ? `${word?.charAt(0).toUpperCase()}${word?.slice(1)}` : '';
|
||||
|
||||
export const camelise = str => {
|
||||
return str
|
||||
return str ? str
|
||||
.replace(/(?:^\w|[A-Z]|\b\w)/g, (letter, index) => {
|
||||
return index === 0 ? letter.toLowerCase() : letter.toUpperCase();
|
||||
})
|
||||
.replace(/\s+/g, '');
|
||||
.replace(/\s+/g, '') : str
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -35,3 +35,31 @@ export const useWindowDimensions = () => {
|
||||
|
||||
return { width, height }
|
||||
}
|
||||
|
||||
|
||||
export const useWindowSize = () => {
|
||||
// Initialize state with undefined width/height so server and client renders match
|
||||
// Learn more here: https://joshwcomeau.com/react/the-perils-of-rehydration/
|
||||
const [windowSize, setWindowSize] = useState({
|
||||
width: undefined,
|
||||
height: undefined,
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
// Handler to call on window resize
|
||||
function handleResize() {
|
||||
// Set window width/height to state
|
||||
setWindowSize({
|
||||
width: window.innerWidth,
|
||||
height: window.innerHeight,
|
||||
})
|
||||
}
|
||||
// Add event listener
|
||||
window.addEventListener('resize', handleResize)
|
||||
// Call handler right away so state gets updated with initial window size
|
||||
handleResize()
|
||||
// Remove event listener on cleanup
|
||||
return () => window.removeEventListener('resize', handleResize)
|
||||
}, []) // Empty array ensures that effect is only run on mount
|
||||
return windowSize
|
||||
}
|
@ -23,7 +23,7 @@ const InfoLayout = ({ title, subtitle, image, children, theme }) => (
|
||||
{children}
|
||||
</Content>
|
||||
<Hero image={image}>
|
||||
<Header theme={{ foreground: theme.background, background: 'transparent', }} miniHeader />
|
||||
<Header theme={theme} miniHeader />
|
||||
<H1>{title}</H1>
|
||||
<H1
|
||||
css={`
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Link } from 'react-router-dom'
|
||||
import styled from 'styled-components'
|
||||
import { colours } from '../../assets/theme'
|
||||
import { colours, screenSizes } from '../../assets/theme'
|
||||
import { ImageLogo as Logo } from '../../components/Logo'
|
||||
|
||||
const heroWidth = 'calc(100vw - 600px - 4em)'
|
||||
@ -15,10 +15,10 @@ export const Wrapper = styled.div`
|
||||
overflow-y: scroll;
|
||||
|
||||
|
||||
@media screen and (max-width: 1200px) {
|
||||
@media screen and (max-width: ${screenSizes.lg}px) {
|
||||
padding: 1.5em;
|
||||
}
|
||||
@media screen and (max-width: 800px) {
|
||||
@media screen and (max-width: ${screenSizes.sm}px) {
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
@ -79,16 +79,9 @@ export const Hero = styled.div`
|
||||
margin-bottom: 0.2em;
|
||||
&:not(:last-of-type) {
|
||||
font-size: 12vw;
|
||||
|
||||
@media screen and (max-height: 600px) {
|
||||
font-size: 20vh;
|
||||
}
|
||||
@media screen and (max-width: 1200px) {
|
||||
font-size: 20vh;
|
||||
}
|
||||
}}
|
||||
|
||||
@media screen and (max-width: 1000px) {
|
||||
@media screen and (max-width: ${screenSizes.md}px) {
|
||||
display: none;
|
||||
}
|
||||
`
|
||||
|
@ -1,5 +1,5 @@
|
||||
import styled from 'styled-components'
|
||||
import { colours } from '../../assets/theme'
|
||||
import { colours, screenSizes } from '../../assets/theme'
|
||||
import { H1 } from '../../components/Text'
|
||||
import Link from '../../components/Link'
|
||||
|
||||
@ -15,10 +15,10 @@ export const Wrapper = styled.div`
|
||||
box-sizing: border-box;
|
||||
|
||||
|
||||
@media screen and (max-width: 1200px) {
|
||||
@media screen and (max-width: ${screenSizes.lg}px) {
|
||||
padding: 1.5em;
|
||||
}
|
||||
@media screen and (max-width: 800px) {
|
||||
@media screen and (max-width: ${screenSizes.sm}px) {
|
||||
padding: 1em;
|
||||
}
|
||||
`
|
||||
|
@ -1,5 +1,5 @@
|
||||
import styled from 'styled-components'
|
||||
import { colours } from '../../assets/theme'
|
||||
import { colours, screenSizes } from '../../assets/theme'
|
||||
import bg from '../../assets/img/hero/1lg.png'
|
||||
|
||||
// import { H1 } from '../../components/Text'
|
||||
@ -23,13 +23,6 @@ export const Wrapper = styled.div`
|
||||
h2 {
|
||||
color: ${colours.midnightDarker};
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1200px) {
|
||||
/* padding: 1.5em; */
|
||||
}
|
||||
@media screen and (max-width: 800px) {
|
||||
/* padding: 1em; */
|
||||
}
|
||||
`
|
||||
|
||||
export const Top = styled.div`
|
||||
@ -72,19 +65,7 @@ export const Hero = styled.div`
|
||||
justify-content: space-between;
|
||||
pointer-events: none;
|
||||
|
||||
/*
|
||||
h1:not(:last-of-type) {
|
||||
font-size: 30vh;
|
||||
|
||||
@media screen and (max-height: 600px) {
|
||||
font-size: 20vh;
|
||||
}
|
||||
@media screen and (max-width: 1200px) {
|
||||
font-size: 20vh;
|
||||
}
|
||||
} */
|
||||
|
||||
@media screen and (max-width: 1000px) {
|
||||
@media screen and (max-width: ${screenSizes.md}px) {
|
||||
display: none;
|
||||
}
|
||||
`
|
||||
@ -98,7 +79,7 @@ export const LoaderWrapper = styled.div`
|
||||
top: 0;
|
||||
width: calc(600px + 4em);
|
||||
|
||||
@media screen and (max-width: 1000px) {
|
||||
@media screen and (max-width: ${screenSizes.md}px) {
|
||||
width: 100vw;
|
||||
}
|
||||
`
|
||||
@ -143,7 +124,7 @@ export const TaglineContainer = styled.div`
|
||||
margin-bottom: 0.2em;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 1000px) {
|
||||
@media screen and (max-width: ${screenSizes.md}px) {
|
||||
h1 {
|
||||
color: ${colours.rose};
|
||||
font-size: 24px;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* eslint-disable react/prop-types */
|
||||
import { isWithinInterval } from 'date-fns'
|
||||
import { h } from 'preact'
|
||||
import { Fragment, h } from 'preact'
|
||||
import { H1, H2 } from '../../components/Text'
|
||||
import strings from '../../data/strings'
|
||||
import { useEventApi } from '../../hooks/data'
|
||||
@ -24,7 +24,6 @@ const Series = () => {
|
||||
|
||||
pastSeries.push(series)
|
||||
return false
|
||||
|
||||
})
|
||||
|
||||
|
||||
@ -32,12 +31,14 @@ const Series = () => {
|
||||
<Page title={strings.en.series}>
|
||||
<Content>
|
||||
<SeriesGrid>
|
||||
<H1 colour={colours.rose}>{strings.en.currentSeries}</H1>
|
||||
<SeriesRow>
|
||||
{currentSeries.map(series => (
|
||||
<SeriesCard series={series} />
|
||||
))}
|
||||
</SeriesRow>
|
||||
{currentSeries.map(series => (
|
||||
<Fragment>
|
||||
<H1 colour={colours.rose}>{strings.en.currentSeries}</H1>
|
||||
<SeriesRow>
|
||||
<SeriesCard series={series} />
|
||||
</SeriesRow>
|
||||
</Fragment>
|
||||
))}
|
||||
<H1 colour={colours.rose}>{strings.en.pastSeries}</H1>
|
||||
<SeriesRow>
|
||||
{pastSeries.map(series => (
|
||||
|
@ -16,18 +16,14 @@ import {
|
||||
TrailerContainer,
|
||||
} from './styles'
|
||||
|
||||
import config from '../../data/config'
|
||||
import Page from '../../layouts/Page'
|
||||
import { splitArray } from '../../helpers/utils'
|
||||
import Header from '../../components/Header'
|
||||
import theme from '../../assets/theme'
|
||||
|
||||
const SeriesPage = ({ data }) => {
|
||||
|
||||
const credits = `
|
||||
const credits = data.credits ? `
|
||||
## Credits
|
||||
${data.credits}
|
||||
`
|
||||
` : null
|
||||
|
||||
const dateString = `${new Date()}`
|
||||
let tzShort =
|
||||
@ -52,7 +48,7 @@ const SeriesPage = ({ data }) => {
|
||||
<InfoContent>
|
||||
<H1>{data.title}:</H1>
|
||||
<H1>{data.subtitle}</H1>
|
||||
<Markdown withLinebreaks theme={data.theme}>{data.description}</Markdown>
|
||||
{data.description ? <Markdown withLinebreaks theme={data.theme}>{data.description}</Markdown> : null}
|
||||
|
||||
{data.trailer ? (
|
||||
<TrailerContainer>
|
||||
@ -101,7 +97,7 @@ const SeriesPage = ({ data }) => {
|
||||
))}
|
||||
</Fragment>
|
||||
) : null}
|
||||
{data.credits ? <InfoContent>
|
||||
{credits ? <InfoContent>
|
||||
<Title>Credits</Title>
|
||||
<Markdown theme={data.theme}>{credits}</Markdown>
|
||||
</InfoContent> : null}
|
||||
|
Loading…
Reference in New Issue
Block a user