Skip to content

Commit

Permalink
🐛 Improve CLS and fix a bug discovered #1876 (#2094)
Browse files Browse the repository at this point in the history
* 🎨 improve cls with adding picture tag and matchmedia, fix promo event

* 🎨 remove console

* 🎨 remove unused hook
  • Loading branch information
BorghildSelle authored Feb 13, 2024
1 parent be5cb77 commit 7a70cff
Show file tree
Hide file tree
Showing 10 changed files with 71 additions and 56 deletions.
43 changes: 43 additions & 0 deletions web/lib/hooks/useMediaQuery.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { useEffect, useLayoutEffect, useState } from 'react'

const getMatches = (query: string): boolean => {
// Prevents SSR issues
if (typeof window !== 'undefined') {
return window.matchMedia(query).matches
}
return false
}

/**
* Returns true if the given media query matches.
* Returns undefined until the first render occured to prevent hydration errors.
* @param query A media query as string
* @returns
*/
export function useMediaQuery(query: string): boolean | undefined {
const [hasMatch, setHasMatches] = useState<boolean>(getMatches(query))
const [initialLoad, setInitialLoad] = useState(true)

useLayoutEffect(() => {
if (initialLoad) {
setInitialLoad(false)
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])

function handleChange() {
setHasMatches(getMatches(query))
}

useEffect(() => {
const matchMedia = window.matchMedia(query)
handleChange()
matchMedia.addEventListener('change', handleChange)
return () => {
matchMedia.removeEventListener('change', handleChange)
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [query])

return initialLoad ? undefined : hasMatch
}
5 changes: 2 additions & 3 deletions web/lib/hooks/usePaginationPadding.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import useWindowSize from './useWindowSize'
import { useMediaQuery } from './useMediaQuery'

function usePaginationPadding() {
const { width } = useWindowSize()
const isMobile = width && width < 375
const isMobile = useMediaQuery(`(max-width: 375px)`)
return isMobile ? 0 : 1
}

Expand Down
32 changes: 0 additions & 32 deletions web/lib/hooks/useWindowSize.ts

This file was deleted.

13 changes: 9 additions & 4 deletions web/pageComponents/shared/Hero/FullImageHero.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import styled from 'styled-components'
import type { HeroType, ImageWithCaptionData } from 'types'
import useWindowSize from '../../../lib/hooks/useWindowSize'
import { useSanityLoader } from '../../../lib/hooks/useSanityLoader'
import Image, { Ratios } from '../SanityImage'
import { StyledCaption } from '../image/StyledCaption'

Expand All @@ -25,11 +25,16 @@ const FullScreenHero = ({ figure }: FullImageHeroType) => {
}

const NarrowHero = ({ figure }: FullImageHeroType) => {
const { width } = useWindowSize()
// 4:3 for small screens and 10:3 for large screens
const aspectRatio = width && width < 750 ? Ratios.THREE_TO_FOUR : Ratios.THREE_TO_TEN
const desktopUrl = useSanityLoader(figure.image, 4096, Ratios.THREE_TO_TEN)

return <Image maxWidth={4096} aspectRatio={aspectRatio} image={figure.image} sizes={imageSizes} priority />
// Using picture with mobile and dekstop source to avoid initial load layout shift between aspect ratio
return (
<picture>
<source srcSet={desktopUrl.src} media="(min-width: 750px)" />
<Image maxWidth={1024} aspectRatio={Ratios.THREE_TO_FOUR} image={figure.image} sizes={imageSizes} priority />
</picture>
)
}

const RatioHero = ({ ratio, figure }: FullImageHeroType) => {
Expand Down
6 changes: 3 additions & 3 deletions web/pageComponents/topicPages/FullWidthImage.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { FullWidthImageData } from '../../types/types'
import Image, { Ratios } from '../shared/SanityImage'
import { StyledCaption } from '../shared/image/StyledCaption'
import useWindowSize from '../../lib/hooks/useWindowSize'
import { useMediaQuery } from '../../lib/hooks/useMediaQuery'

type TeaserProps = {
data: FullWidthImageData
Expand All @@ -11,9 +11,9 @@ type TeaserProps = {
const FullWidthImage = ({ data, anchor }: TeaserProps) => {
const { image, attribution, caption } = data.image
const { aspectRatio } = data.designOptions
const { width } = useWindowSize()
const isMobile = useMediaQuery(`(max-width: 750px)`)

const ratio = (width && width < 750) || aspectRatio === Ratios.ONE_TO_TWO ? Ratios.ONE_TO_TWO : Ratios.THREE_TO_TEN
const ratio = isMobile || aspectRatio === Ratios.ONE_TO_TWO ? Ratios.ONE_TO_TWO : Ratios.THREE_TO_TEN

if (!image) return null
return (
Expand Down
6 changes: 3 additions & 3 deletions web/pageComponents/topicPages/KeyNumbers/KeyNumbers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import KeyNumberItem from './KeyNumberItem'
import ReadMoreLink from '../../../pageComponents/shared/ReadMoreLink'
import RichText from '../../shared/portableText/RichText'
import { Carousel } from '../../shared/Carousel'
import useWindowSize from '../../../lib/hooks/useWindowSize'
import { useMediaQuery } from '../../../lib/hooks/useMediaQuery'

const Disclaimer = styled.div`
@media (min-width: 1300px) {
Expand Down Expand Up @@ -55,9 +55,9 @@ type KeyNumbersProps = {
}
export default function ({ data, anchor }: KeyNumbersProps) {
const { title, items, designOptions, ingress, action, disclaimer, useHorizontalScroll } = data
const { width } = useWindowSize()
const isMobile = useMediaQuery(`(max-width: 800px)`)

const renderScroll = useHorizontalScroll && Boolean(width && width <= 800)
const renderScroll = useHorizontalScroll && isMobile
const Wrapper = renderScroll
? ({ children }: { children: React.ReactNode }) => (
<HorizontalWrapper>
Expand Down
6 changes: 3 additions & 3 deletions web/pageComponents/topicPages/PromoTileArray.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import type { PromoTileArrayData, PromoTileData } from '../../types/types'
import Image, { Ratios } from '../shared/SanityImage'
import PromotileTitleText from '../shared/portableText/PromoTileTitleText'
import { PromoTileButton } from './PromoTileButton'
import useWindowSize from '../../lib/hooks/useWindowSize'
import { Carousel } from '../shared/Carousel'
import { useMediaQuery } from '../../lib/hooks/useMediaQuery'

const { Header, Action, Media } = Card

Expand Down Expand Up @@ -57,11 +57,11 @@ const StyledCard = styled(Card)`
`

const PromoTileArray = ({ data, anchor }: { data: PromoTileArrayData; anchor?: string }) => {
const { width } = useWindowSize()
const isMobile = useMediaQuery(`(max-width: 800px)`)

if (!data.group) return null

const renderScroll = data.useHorizontalScroll || Boolean(width && width <= 800)
const renderScroll = data.useHorizontalScroll || isMobile

const richTitle = (title: PortableTextBlock[], hasImage: boolean) => {
return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ const MultipleEventCards = ({
)
})
}
if (eventPromotionSettings?.pastEventsCount) {
if (eventPromotionSettings?.promotePastEvents && eventPromotionSettings?.pastEventsCount) {
data = data.slice(0, eventPromotionSettings.pastEventsCount)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ import NewsCard from '../../cards/NewsCard'
import TopicPageCard from '../../cards/TopicPageCard'
import PeopleCard from '../../cards/PeopleCard/PeopleCard'
import MultipleEventCards from './MultipleEventCards'
import useWindowSize from '../../../lib/hooks/useWindowSize'
import { Carousel } from '../../shared/Carousel'
import { BackgroundContainer } from '@components/Backgrounds'
import { useMediaQuery } from '../../../lib/hooks/useMediaQuery'

const CardsWrapper = styled.div`
width: 100%;
Expand Down Expand Up @@ -125,8 +125,8 @@ const MultiplePromotions = ({
}
}

const { width } = useWindowSize()
const renderScroll = useHorizontalScroll || Boolean(width && width <= 800)
const isMobile = useMediaQuery(`(max-width: 800px)`)
const renderScroll = useHorizontalScroll || isMobile

if (variant === 'promoteEvents') {
return (
Expand Down
8 changes: 4 additions & 4 deletions web/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 7a70cff

Please sign in to comment.