Skip to content
Snippets Groups Projects
Commit 7c0b915e authored by Tarje.Lavik's avatar Tarje.Lavik
Browse files

Fix lint errors and missing PT component

parent 2013aa39
No related branches found
No related tags found
No related merge requests found
/* eslint-disable no-unused-vars */
/**
* ! Important in optimizing images
*
* Keep the values in sync between:
* - `deviceSizes` in `next.config.js`
* - `deviceSizes` in `image.ts`
*
* ! Recommended
* NextJs optimize images according to your viewport. This is wonderful for mobile, but for desktop with a 4k screen, NextJs would
* download the 3840px version of your image.
*
* To workaround this unfortunate situation, I highly recommend you pass `size` to images with the highest width value being the
* max width an image can have on your site.
*
* For example, content on my site is centered and cannot be more than 960px wide, thus I make sure that 960 is in `deviceSizes` and
* I use `Sizes.main` to limit the image to only 960px. This considerably reduce the size in KB of my images and they're much
* better optimized on screens larger than 960px.
*
* This file is a way to generate the strings to pass to Image's `size` property and put the results in an Enum for easier consumption
*/
const deviceSizes = [320, 480, 640, 750, 828, 960, 1080, 1200, 1440, 1920, 2048, 2560, 3840]
const deviceSizesMax = Math.max(...deviceSizes)
/**
* ? `generateSizes` will create the strings necessary for `Sizes` enum
*
* ? Simply uncomment the `console.log` and adjust values
*/
const generateSizes = (upperLimit: number = deviceSizesMax): string => {
const sizes = [...deviceSizes.filter((v) => v < upperLimit), upperLimit]
return sizes
.map((v, i) => {
return i < sizes.length - 1 ? ` (max-width: ${v}px) ${v}px` : ` ${v}px`
})
.join()
}
// console.log(generateSizes(960)) // I use a variable, but since it's easier to understand with a real number...
// console.log(generateSizes())
export enum Sizes {
main = '(max-width: 320px) 320px, (max-width: 480px) 480px, (max-width: 640px) 640px, (max-width: 750px) 750px, (max-width: 828px) 828px, 960px',
full = '(max-width: 320px) 320px, (max-width: 480px) 480px, (max-width: 640px) 640px, (max-width: 750px) 750px, (max-width: 828px) 828px, (max-width: 960px) 960px, (max-width: 1080px) 1080px, (max-width: 1200px) 1200px, (max-width: 1440px) 1440px, (max-width: 1920px) 1920px, (max-width: 2048px) 2048px, (max-width: 2560px) 2560px, 3840px',
}
import { Box, chakra } from '@chakra-ui/react'
import NextImage from 'next/image'
const CoverImg = chakra(NextImage, {
shouldForwardProp: (prop) =>
['width', 'height', 'src', 'alt', 'quality', 'placeholder', 'blurDataURL', 'loader '].includes(
prop,
),
})
const myLoader = ({ src, width, quality }) => {
return `${src}?w=${width}&q=${quality}`
}
export const Image = (props) => {
const { src, alt, ...rest } = props
return (
<Box pos="relative" cursor="pointer" className="group" {...rest}>
<CoverImg
w="auto"
h="auto"
loader={myLoader}
width={600}
quality={50}
height={384}
placeholder="blur"
src={src}
alt={alt}
transition="all 0.2s"
_groupHover={{
transform: 'scale(1.05)',
}}
/>
</Box>
)
}
import { chakra, ThemingProps, useStyleConfig } from '@chakra-ui/react'
import NextImage, { ImageProps as NextImageProps } from 'next/image'
import { ReactElement } from 'react'
import { Sizes } from './image'
// TODO review props when NextJs is updated so we don't have to defined it here
/**
* ? Because NextJs typing is preventing auto-suggest for layout, width and height,
* ? we declare the styles differently in this component and will manage the switch
* ? to NextJs typings when calling NextJs `next/image` component
*/
type LayoutValue = 'fixed' | 'intrinsic' | 'responsive' | undefined
type LayoutAndSize = { layout: 'fill' } | { layout: LayoutValue; height: number; width: number }
/**
* Types for the Image component itself
*/
type ImageProps = Pick<
NextImageProps,
| 'className'
| 'loading'
| 'objectFit'
| 'objectPosition'
| 'priority'
| 'quality'
| 'src'
| 'unoptimized'
> &
Pick<Required<NextImageProps>, 'alt'> &
Pick<ThemingProps, 'variant'> & {
dimensions?: [number, number]
layout?: 'fill' | LayoutValue
sizes?: Sizes // could be a string too, this one is just a way to make it easier
}
/**
* Wraps NextJs `next/image` component in Chakra's factory function
* This is what will allow to use the theme and the styling properties on the component
*/
const ImageWithChakra = chakra(
({
className,
dimensions = [0, 0],
layout = 'fill',
loading,
objectFit,
objectPosition,
priority,
quality,
sizes,
src,
unoptimized,
...nextjsInternals
}: ImageProps): ReactElement => {
/**
* ? As explained earlier, NextJs typing is preventing auto-suggest for layout, width and height
* ? Here we actually convert our component typing to NextJs typing
*/
const [width, height] = dimensions
const layoutAndSize: LayoutAndSize =
height > 0 || width > 0
? { height, layout: layout === 'fill' ? 'intrinsic' : layout, width }
: { layout: 'fill' }
return (
<NextImage
className={className}
loading={loading}
objectFit={objectFit}
objectPosition={objectPosition}
priority={priority}
quality={quality}
sizes={sizes}
src={src}
unoptimized={unoptimized}
// eslint-disable-next-line react/jsx-props-no-spreading
{...layoutAndSize}
// eslint-disable-next-line react/jsx-props-no-spreading
{...nextjsInternals}
/>
)
},
)
export const Image = ({ variant, ...props }: ImageProps): ReactElement => {
/**
* ? This components serves as an interface to pass Chakra's styles
* ? You can use the theme and/or styling properties (eg. backgroundColor='red.200')
*/
const styles = useStyleConfig('Image', { variant })
// eslint-disable-next-line react/jsx-props-no-spreading
return <ImageWithChakra sx={styles} {...props} />
}
/* import { Box, chakra } from '@chakra-ui/react'
import NextImage from 'next/image'
const CoverImg = chakra(NextImage, {
shouldForwardProp: (prop) =>
['width', 'height', 'src', 'alt', 'quality', 'placeholder', 'blurDataURL', 'loader '].includes(
prop,
),
})
const myLoader = ({ src, width, quality }) => {
return `${src}?w=${width}&q=${quality}`
}
export const Image = (props) => {
const { src, alt, ...rest } = props
return (
<Box pos="relative" cursor="pointer" className="group" {...rest}>
<CoverImg
w="auto"
h="auto"
loader={myLoader}
width={600}
quality={50}
height={384}
placeholder="blur"
src={src}
alt={alt}
transition="all 0.2s"
_groupHover={{
transform: 'scale(1.05)',
}}
/>
</Box>
)
}
*/
...@@ -5,7 +5,9 @@ import RenderSections from '../Sections/RenderSection' ...@@ -5,7 +5,9 @@ import RenderSections from '../Sections/RenderSection'
import License from '../License' import License from '../License'
import React from 'react' import React from 'react'
import Publisher from '../Publisher' import Publisher from '../Publisher'
import Image from '../Image' // import { Image } from '../Image'
// import footerBorder from '../../public/img/taakeheimen-footer.svg'
/* const MenuItem = ({ children }) => ( /* const MenuItem = ({ children }) => (
<Text <Text
...@@ -35,10 +37,14 @@ export default function Footer(props) { ...@@ -35,10 +37,14 @@ export default function Footer(props) {
gridArea="footer" gridArea="footer"
maxW="full" maxW="full"
minH="100px" minH="100px"
py="2" mt="10"
py="6"
px="0" px="0"
zIndex="100" zIndex="100"
color={color} color={color}
backgroundImage={`url('${process.env.NEXT_PUBLIC_BASE_PATH}/img/taakeheimen-footer.svg')`}
backgroundPosition="50% 4%"
backgroundRepeat="no-repeat"
> >
<Flex pl="5"> <Flex pl="5">
<Button variant="link" onClick={toggleColorMode}> <Button variant="link" onClick={toggleColorMode}>
...@@ -46,7 +52,11 @@ export default function Footer(props) { ...@@ -46,7 +52,11 @@ export default function Footer(props) {
</Button> </Button>
</Flex> </Flex>
<Image src={`${process.env.NEXT_PUBLIC_BASE_PATH}/img/taakeheimen-footer.svg`} alt="" /> {/* <Image
layout="responsive"
src={`${process.env.NEXT_PUBLIC_BASE_PATH}/img/taakeheimen-footer.svg`}
alt=""
/> */}
<Container maxW="4xl" p="0" sx={{ perspective: '492px' }}> <Container maxW="4xl" p="0" sx={{ perspective: '492px' }}>
{/* <Flex pb="0"> {/* <Flex pb="0">
......
import * as React from 'react' import * as React from 'react'
import Head from 'next/head' import Head from 'next/head'
const basePath = process.env.NEXT_PUBLIC_BASE_PATH
export default function Meta() { export default function Meta() {
return ( return (
<React.Fragment> <React.Fragment>
<Head> <Head>
<link rel="apple-touch-icon" sizes="180x180" href="/favicon/apple-touch-icon.png" /> <link
<link rel="icon" type="image/png" sizes="32x32" href="/favicon/favicon-32x32.png" /> rel="apple-touch-icon"
<link rel="icon" type="image/png" sizes="16x16" href="/favicon/favicon-16x16.png" /> sizes="180x180"
<link rel="manifest" href="/favicon/site.webmanifest" /> href={`${basePath}/favicon/apple-touch-icon.png`}
<link rel="mask-icon" href="/favicon/safari-pinned-tab.svg" color="#000000" /> />
<link rel="shortcut icon" href="/favicon/favicon.ico" /> <link
rel="icon"
type="image/png"
sizes="32x32"
href={`${basePath}/favicon/favicon-32x32.png`}
/>
<link
rel="icon"
type="image/png"
sizes="16x16"
href={`${basePath}/favicon/favicon-16x16.png`}
/>
<link rel="manifest" href={`${basePath}/favicon/site.webmanifest`} />
<link rel="mask-icon" href={`${basePath}/favicon/safari-pinned-tab.svg`} color="#000000" />
<link rel="shortcut icon" href={`${basePath}/favicon/favicon.ico`} />
<meta name="msapplication-TileColor" content="#000000" /> <meta name="msapplication-TileColor" content="#000000" />
<meta name="msapplication-config" content="/favicon/browserconfig.xml" /> <meta name="msapplication-config" content={`${basePath}/favicon/browserconfig.xml`} />
<meta name="theme-color" content="#000" /> <meta name="theme-color" content="#000" />
<link rel="alternate" type="application/rss+xml" href="/feed.xml" /> <link rel="alternate" type="application/rss+xml" href={`${basePath}/feed.xml`} />
<meta name="description" content={'A statically generated blog example using Next.js.'} /> <meta name="description" content={'A statically generated blog example using Next.js.'} />
{/* <meta property="og:image" content={HOME_OG_IMAGE_URL} /> */} {/* <meta property="og:image" content={HOME_OG_IMAGE_URL} /> */}
</Head> </Head>
......
import { imageBuilder } from '../../lib/sanity' import { imageBuilder } from '../../lib/sanity'
import { Flex, Grid, Box, Image } from '@chakra-ui/react' import { Flex, Grid, Box } from '@chakra-ui/react'
import Caption from './shared/caption' import Caption from './shared/caption'
import { Image } from '../Image'
export default function IllustrationWithCaption(props) { export default function IllustrationWithCaption(props) {
if ((!props && !props.illustration) || props.disabled === true) { if ((!props && !props.illustration) || props.disabled === true) {
......
...@@ -30,7 +30,7 @@ export default function Page({ data, preview }) { ...@@ -30,7 +30,7 @@ export default function Page({ data, preview }) {
</Box> </Box>
)} )}
<Text mt="5" color="gray.500" fontSize="sm"> <Text mt="10" color="gray.500" fontSize="sm">
Oppdatert: <Date>{_updatedAt}</Date> Oppdatert: <Date>{_updatedAt}</Date>
</Text> </Text>
</Container> </Container>
......
...@@ -3,7 +3,7 @@ import { getAllActors } from '../../lib/api' ...@@ -3,7 +3,7 @@ import { getAllActors } from '../../lib/api'
import { Grid, Avatar, Box, Heading, Flex, Badge, Container } from '@chakra-ui/react' import { Grid, Avatar, Box, Heading, Flex, Badge, Container } from '@chakra-ui/react'
import Layout from '../../components/Layout' import Layout from '../../components/Layout'
import Link from '../../components/Link' import Link from '../../components/Link'
import PortableTextBlock from '../../components/PortableTextBlock' import PortableTextBlock from '../../components/PT/PortableTextBlock'
export default function Actors({ data, preview }) { export default function Actors({ data, preview }) {
/* let actors = data.items.reduce((r, e) => { /* let actors = data.items.reduce((r, e) => {
......
import { getPhysicalExhibitionCopy } from '../../lib/api' import { getPhysicalExhibitionCopy } from '../../lib/api'
import Head from 'next/head' import Head from 'next/head'
import { Container, Heading } from '@chakra-ui/react' import { Container, Heading } from '@chakra-ui/react'
import PortableTextBlock from '../../components/PortableTextBlock' import PortableTextBlock from '../../components/PT/PortableTextBlock'
import Layout from '../../components/Layout' import Layout from '../../components/Layout'
export default function PhysicalExhibition({ data, preview }) { export default function PhysicalExhibition({ data, preview }) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment