header work WIP
This commit is contained in:
parent
b2fad77434
commit
6d2090eea9
@ -26,6 +26,13 @@ export const textSizes = {
|
|||||||
hg: 200,
|
hg: 200,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const screenSizes = {
|
||||||
|
xs: 670,
|
||||||
|
sm: 800,
|
||||||
|
md: 1000,
|
||||||
|
lg: 1500,
|
||||||
|
}
|
||||||
|
|
||||||
export const defaultTheme = {
|
export const defaultTheme = {
|
||||||
background: colours.midnightDarker, foreground: colours.rose, highlight: colours.highlight
|
background: colours.midnightDarker, foreground: colours.rose, highlight: colours.highlight
|
||||||
}
|
}
|
||||||
|
@ -1,36 +1,66 @@
|
|||||||
import { h } from 'preact'
|
import { h } from 'preact'
|
||||||
import { Link as ReactLink } from 'react-router-dom'
|
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 { ImageLogo } from '../Logo'
|
||||||
|
import { useWindowSize } from '../../hooks/dom'
|
||||||
import Link from '../Link'
|
import Link from '../Link'
|
||||||
|
import { Span } from '../Text'
|
||||||
|
import CrossSvg from '../Svg/Cross'
|
||||||
|
|
||||||
import navigation from '../../data/navigation'
|
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' }) => (
|
const Navigation = ({ theme = {}, lang = 'en', headerTheme }) => navigation[lang].map(navItem => (
|
||||||
<RightBox as="nav">
|
<Link
|
||||||
{navigation[lang].map(navItem => <Link navLink to={navItem.to} href={navItem.href} textProps={{
|
navLink
|
||||||
size: textSizes.xl, colour: theme.foreground || colours.rose
|
to={navItem.to}
|
||||||
}}>{navItem.label}</Link>)}
|
href={navItem.href}
|
||||||
</RightBox>
|
textProps={{
|
||||||
)
|
size: textSizes.xl,
|
||||||
|
colour: headerTheme.foreground || theme.foreground || colours.rose
|
||||||
|
}}>
|
||||||
|
{navItem.label}
|
||||||
|
</Link>
|
||||||
|
))
|
||||||
|
|
||||||
|
const NavigationModal = ({ theme = {}, lang = 'en', headerTheme, toggleMenuOpen, ...rest }) => (
|
||||||
const BigHeader = ({ theme = {}, lang = 'en', ...rest }) => (
|
<Modal theme={theme} {...rest}>
|
||||||
<Row theme={theme} align="center" justify="space-between" {...rest}>
|
|
||||||
<ReactLink to="/">
|
<ReactLink to="/">
|
||||||
<ImageLogo />
|
<ImageLogo />
|
||||||
</ReactLink>
|
</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>
|
</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
|
export default Header
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
|
import { screenSizes } from '../../assets/theme'
|
||||||
import { Row } from '../Flex'
|
import { Row } from '../Flex'
|
||||||
|
import CrossSvg from '../Svg/Cross'
|
||||||
|
|
||||||
|
|
||||||
export const StyledRow = styled(Row)`
|
export const StyledRow = styled(Row)`
|
||||||
@ -19,12 +21,56 @@ export const StyledRow = styled(Row)`
|
|||||||
padding: 1em;
|
padding: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
a:hover {
|
|
||||||
|
a, span {
|
||||||
|
margin-right: 2em;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
@media screen and (max-width: ${screenSizes.md}px) {
|
||||||
|
margin-right: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
`
|
`
|
||||||
export const RightBox = styled(Row)`
|
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
|
exact: activeOnlyWhenExact
|
||||||
})
|
})
|
||||||
|
|
||||||
console.log({ colour })
|
|
||||||
|
|
||||||
return href ? <A href={href} colour={colour} size={size} fontFamily={navLink ? 'Lunchtype24' : null} {...rest}>{children}</A> : (
|
return href ? <A href={href} colour={colour} size={size} fontFamily={navLink ? 'Lunchtype24' : null} {...rest}>{children}</A> : (
|
||||||
<A as="span" colour={colour} size={size} {...rest}>
|
<A as="span" colour={colour} size={size} {...rest}>
|
||||||
<RRLink to={to} $navLink={navLink} $colour={colour} $selected={match && navLink}>{children}</RRLink>
|
<RRLink to={to} $navLink={navLink} $colour={colour} $selected={match && navLink}>{children}</RRLink>
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
export const slugify = (title) => {
|
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()
|
str = str.toLowerCase()
|
||||||
|
|
||||||
// remove accents, swap ñ for n, etc
|
// remove accents, swap ñ for n, etc
|
||||||
@ -22,11 +25,11 @@ export const capitaliseFirstLetter = word =>
|
|||||||
word ? `${word?.charAt(0).toUpperCase()}${word?.slice(1)}` : '';
|
word ? `${word?.charAt(0).toUpperCase()}${word?.slice(1)}` : '';
|
||||||
|
|
||||||
export const camelise = str => {
|
export const camelise = str => {
|
||||||
return str
|
return str ? str
|
||||||
.replace(/(?:^\w|[A-Z]|\b\w)/g, (letter, index) => {
|
.replace(/(?:^\w|[A-Z]|\b\w)/g, (letter, index) => {
|
||||||
return index === 0 ? letter.toLowerCase() : letter.toUpperCase();
|
return index === 0 ? letter.toLowerCase() : letter.toUpperCase();
|
||||||
})
|
})
|
||||||
.replace(/\s+/g, '');
|
.replace(/\s+/g, '') : str
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -35,3 +35,31 @@ export const useWindowDimensions = () => {
|
|||||||
|
|
||||||
return { width, height }
|
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}
|
{children}
|
||||||
</Content>
|
</Content>
|
||||||
<Hero image={image}>
|
<Hero image={image}>
|
||||||
<Header theme={{ foreground: theme.background, background: 'transparent', }} miniHeader />
|
<Header theme={theme} miniHeader />
|
||||||
<H1>{title}</H1>
|
<H1>{title}</H1>
|
||||||
<H1
|
<H1
|
||||||
css={`
|
css={`
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Link } from 'react-router-dom'
|
import { Link } from 'react-router-dom'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
import { colours } from '../../assets/theme'
|
import { colours, screenSizes } from '../../assets/theme'
|
||||||
import { ImageLogo as Logo } from '../../components/Logo'
|
import { ImageLogo as Logo } from '../../components/Logo'
|
||||||
|
|
||||||
const heroWidth = 'calc(100vw - 600px - 4em)'
|
const heroWidth = 'calc(100vw - 600px - 4em)'
|
||||||
@ -15,10 +15,10 @@ export const Wrapper = styled.div`
|
|||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
|
|
||||||
|
|
||||||
@media screen and (max-width: 1200px) {
|
@media screen and (max-width: ${screenSizes.lg}px) {
|
||||||
padding: 1.5em;
|
padding: 1.5em;
|
||||||
}
|
}
|
||||||
@media screen and (max-width: 800px) {
|
@media screen and (max-width: ${screenSizes.sm}px) {
|
||||||
padding: 1em;
|
padding: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,16 +79,9 @@ export const Hero = styled.div`
|
|||||||
margin-bottom: 0.2em;
|
margin-bottom: 0.2em;
|
||||||
&:not(:last-of-type) {
|
&:not(:last-of-type) {
|
||||||
font-size: 12vw;
|
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;
|
display: none;
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
import { colours } from '../../assets/theme'
|
import { colours, screenSizes } from '../../assets/theme'
|
||||||
import { H1 } from '../../components/Text'
|
import { H1 } from '../../components/Text'
|
||||||
import Link from '../../components/Link'
|
import Link from '../../components/Link'
|
||||||
|
|
||||||
@ -15,10 +15,10 @@ export const Wrapper = styled.div`
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
|
||||||
@media screen and (max-width: 1200px) {
|
@media screen and (max-width: ${screenSizes.lg}px) {
|
||||||
padding: 1.5em;
|
padding: 1.5em;
|
||||||
}
|
}
|
||||||
@media screen and (max-width: 800px) {
|
@media screen and (max-width: ${screenSizes.sm}px) {
|
||||||
padding: 1em;
|
padding: 1em;
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import styled from 'styled-components'
|
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 bg from '../../assets/img/hero/1lg.png'
|
||||||
|
|
||||||
// import { H1 } from '../../components/Text'
|
// import { H1 } from '../../components/Text'
|
||||||
@ -23,13 +23,6 @@ export const Wrapper = styled.div`
|
|||||||
h2 {
|
h2 {
|
||||||
color: ${colours.midnightDarker};
|
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`
|
export const Top = styled.div`
|
||||||
@ -72,19 +65,7 @@ export const Hero = styled.div`
|
|||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
|
|
||||||
/*
|
@media screen and (max-width: ${screenSizes.md}px) {
|
||||||
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) {
|
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
@ -98,7 +79,7 @@ export const LoaderWrapper = styled.div`
|
|||||||
top: 0;
|
top: 0;
|
||||||
width: calc(600px + 4em);
|
width: calc(600px + 4em);
|
||||||
|
|
||||||
@media screen and (max-width: 1000px) {
|
@media screen and (max-width: ${screenSizes.md}px) {
|
||||||
width: 100vw;
|
width: 100vw;
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
@ -143,7 +124,7 @@ export const TaglineContainer = styled.div`
|
|||||||
margin-bottom: 0.2em;
|
margin-bottom: 0.2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 1000px) {
|
@media screen and (max-width: ${screenSizes.md}px) {
|
||||||
h1 {
|
h1 {
|
||||||
color: ${colours.rose};
|
color: ${colours.rose};
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* eslint-disable react/prop-types */
|
/* eslint-disable react/prop-types */
|
||||||
import { isWithinInterval } from 'date-fns'
|
import { isWithinInterval } from 'date-fns'
|
||||||
import { h } from 'preact'
|
import { Fragment, h } from 'preact'
|
||||||
import { H1, H2 } from '../../components/Text'
|
import { H1, H2 } from '../../components/Text'
|
||||||
import strings from '../../data/strings'
|
import strings from '../../data/strings'
|
||||||
import { useEventApi } from '../../hooks/data'
|
import { useEventApi } from '../../hooks/data'
|
||||||
@ -24,7 +24,6 @@ const Series = () => {
|
|||||||
|
|
||||||
pastSeries.push(series)
|
pastSeries.push(series)
|
||||||
return false
|
return false
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@ -32,12 +31,14 @@ const Series = () => {
|
|||||||
<Page title={strings.en.series}>
|
<Page title={strings.en.series}>
|
||||||
<Content>
|
<Content>
|
||||||
<SeriesGrid>
|
<SeriesGrid>
|
||||||
|
{currentSeries.map(series => (
|
||||||
|
<Fragment>
|
||||||
<H1 colour={colours.rose}>{strings.en.currentSeries}</H1>
|
<H1 colour={colours.rose}>{strings.en.currentSeries}</H1>
|
||||||
<SeriesRow>
|
<SeriesRow>
|
||||||
{currentSeries.map(series => (
|
|
||||||
<SeriesCard series={series} />
|
<SeriesCard series={series} />
|
||||||
))}
|
|
||||||
</SeriesRow>
|
</SeriesRow>
|
||||||
|
</Fragment>
|
||||||
|
))}
|
||||||
<H1 colour={colours.rose}>{strings.en.pastSeries}</H1>
|
<H1 colour={colours.rose}>{strings.en.pastSeries}</H1>
|
||||||
<SeriesRow>
|
<SeriesRow>
|
||||||
{pastSeries.map(series => (
|
{pastSeries.map(series => (
|
||||||
|
@ -16,18 +16,14 @@ import {
|
|||||||
TrailerContainer,
|
TrailerContainer,
|
||||||
} from './styles'
|
} from './styles'
|
||||||
|
|
||||||
import config from '../../data/config'
|
|
||||||
import Page from '../../layouts/Page'
|
import Page from '../../layouts/Page'
|
||||||
import { splitArray } from '../../helpers/utils'
|
import { splitArray } from '../../helpers/utils'
|
||||||
import Header from '../../components/Header'
|
|
||||||
import theme from '../../assets/theme'
|
|
||||||
|
|
||||||
const SeriesPage = ({ data }) => {
|
const SeriesPage = ({ data }) => {
|
||||||
|
const credits = data.credits ? `
|
||||||
const credits = `
|
|
||||||
## Credits
|
## Credits
|
||||||
${data.credits}
|
${data.credits}
|
||||||
`
|
` : null
|
||||||
|
|
||||||
const dateString = `${new Date()}`
|
const dateString = `${new Date()}`
|
||||||
let tzShort =
|
let tzShort =
|
||||||
@ -52,7 +48,7 @@ const SeriesPage = ({ data }) => {
|
|||||||
<InfoContent>
|
<InfoContent>
|
||||||
<H1>{data.title}:</H1>
|
<H1>{data.title}:</H1>
|
||||||
<H1>{data.subtitle}</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 ? (
|
{data.trailer ? (
|
||||||
<TrailerContainer>
|
<TrailerContainer>
|
||||||
@ -101,7 +97,7 @@ const SeriesPage = ({ data }) => {
|
|||||||
))}
|
))}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
) : null}
|
) : null}
|
||||||
{data.credits ? <InfoContent>
|
{credits ? <InfoContent>
|
||||||
<Title>Credits</Title>
|
<Title>Credits</Title>
|
||||||
<Markdown theme={data.theme}>{credits}</Markdown>
|
<Markdown theme={data.theme}>{credits}</Markdown>
|
||||||
</InfoContent> : null}
|
</InfoContent> : null}
|
||||||
|
Loading…
Reference in New Issue
Block a user