Skip to content

Commit

Permalink
feat: Add useScreenResize hook (SFS-1509) (#2487)
Browse files Browse the repository at this point in the history
## What's the purpose of this pull request?

This PR intends to add a hook to resize depending on the current screen
size.

It's related to the performance POC #2404.

## How it works?

It checks the user's screen size (or manual browser resizing) and
returns the value corresponding if is mobile or not.

### Starters Deploy Preview

vtex-sites/starter.store#562
  • Loading branch information
lucasfp13 authored Oct 14, 2024
1 parent 79ad36c commit c94a768
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 16 deletions.
10 changes: 6 additions & 4 deletions packages/core/src/components/common/Footer/FooterLinks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
import { useState } from 'react'

import Link from 'src/components/ui/Link'
import useScreenResize from 'src/sdk/ui/useScreenResize'

type Item = {
url: string
Expand Down Expand Up @@ -38,6 +39,7 @@ export interface FooterLinksProps {
}

function FooterLinks({ links }: FooterLinksProps) {
const { isDesktop } = useScreenResize()
const [indicesExpanded, setIndicesExpanded] = useState<Set<number>>(
new Set([])
)
Expand All @@ -53,7 +55,7 @@ function FooterLinks({ links }: FooterLinksProps) {

return (
<section data-fs-footer data-fs-footer-links>
<div className="display-mobile">
{!isDesktop && (
<UIAccordion indices={indicesExpanded} onChange={onChange}>
{links.map(({ sectionTitle, items }) => (
<UIAccordionItem key={sectionTitle}>
Expand All @@ -64,9 +66,9 @@ function FooterLinks({ links }: FooterLinksProps) {
</UIAccordionItem>
))}
</UIAccordion>
</div>
)}

<div className="hidden-mobile">
{isDesktop && (
<nav data-fs-footer-links-columns aria-label="Footer Links Navigation">
{links.map(({ sectionTitle, items }) => (
<div key={sectionTitle}>
Expand All @@ -75,7 +77,7 @@ function FooterLinks({ links }: FooterLinksProps) {
</div>
))}
</nav>
</div>
)}
</section>
)
}
Expand Down
5 changes: 4 additions & 1 deletion packages/core/src/components/navigation/Navbar/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import Link from 'src/components/ui/Link'
import { useOverrideComponents } from 'src/sdk/overrides/OverrideContext'

import type { NavbarProps as SectionNavbarProps } from '../../sections/Navbar'
import useScreenResize from 'src/sdk/ui/useScreenResize'

export interface NavbarProps {
/**
Expand Down Expand Up @@ -78,6 +79,8 @@ function Navbar({
} = useOverrideComponents<'Navbar'>()
const scrollDirection = useScrollDirection()
const { openNavbar, navbar: displayNavbar } = useUI()
const { isDesktop } = useScreenResize()

const searchMobileRef = useRef<SearchInputRef>(null)
const [searchExpanded, setSearchExpanded] = useState(false)

Expand Down Expand Up @@ -157,7 +160,7 @@ function Navbar({
</NavbarRow.Component>
</NavbarHeader.Component>

<NavbarLinks links={links} region={region} className="hidden-mobile" />
{isDesktop && <NavbarLinks links={links} region={region} />}

{displayNavbar && (
<NavbarSlider
Expand Down
6 changes: 4 additions & 2 deletions packages/core/src/components/search/Filter/Filter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { gql } from '@generated'
import { ProductGalleryProps } from 'src/components/ui/ProductGallery/ProductGallery'
import { useOverrideComponents } from 'src/sdk/overrides/OverrideContext'
import { useFilter } from 'src/sdk/search/useFilter'
import useScreenResize from 'src/sdk/ui/useScreenResize'

interface Props {
/**
Expand Down Expand Up @@ -35,17 +36,18 @@ function Filter({

const filter = useFilter(allFacets)
const { filter: displayFilter } = useUI()
const { isDesktop } = useScreenResize()

return (
<>
<div className="hidden-mobile">
{isDesktop && (
<FilterDesktop.Component
{...FilterDesktop.props}
{...filter}
testId={testId}
title={filterCmsData?.title}
/>
</div>
)}

{displayFilter && (
<Suspense fallback={null}>
Expand Down
16 changes: 9 additions & 7 deletions packages/core/src/components/sections/RegionBar/RegionBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Section from '../Section/Section'
import styles from './section.module.scss'
import { RegionBarDefaultComponents } from './DefaultComponents'
import { getOverridableSection } from '../../..//sdk/overrides/getOverriddenSection'
import useScreenResize from 'src/sdk/ui/useScreenResize'

type RegionBarSectionProps = {
/**
Expand All @@ -27,14 +28,15 @@ type RegionBarSectionProps = {
buttonIcon?: RegionBarProps['buttonIcon']
}

function RegionBarSection({
className = 'display-mobile',
...otherProps
}: RegionBarSectionProps) {
function RegionBarSection({ ...otherProps }: RegionBarSectionProps) {
const { isMobile } = useScreenResize()

return (
<Section className={`${styles.section} section-region-bar ${className}`}>
<RegionBar {...otherProps} />
</Section>
isMobile && (
<Section className={`${styles.section} section-region-bar`}>
<RegionBar {...otherProps} />
</Section>
)
)
}

Expand Down
8 changes: 6 additions & 2 deletions packages/core/src/components/ui/Carousel/Carousel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import type { PropsWithChildren } from 'react'
import { Carousel as UICarousel } from '@faststore/ui'
import type { CarouselProps as UICarouselProps } from '@faststore/ui'

import useScreenResize from 'src/sdk/ui/useScreenResize'

export type CarouselProps = {
id?: string
testId?: string
Expand All @@ -21,15 +23,17 @@ function Carousel({
variant = 'scroll',
infiniteMode = false,
}: PropsWithChildren<CarouselProps>) {
const isMobile = window.innerWidth <= 768
const { loading, isTablet, isMobile } = useScreenResize()

if (loading) return null

return (
<UICarousel
id={id}
testId={testId}
variant={variant}
infiniteMode={infiniteMode}
itemsPerPage={isMobile ? 1.6 : itemsPerPage}
itemsPerPage={isTablet || isMobile ? 1.6 : itemsPerPage}
>
{children}
</UICarousel>
Expand Down
43 changes: 43 additions & 0 deletions packages/core/src/sdk/ui/useScreenResize.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { useEffect, useState } from 'react'

// We are using the Moto G Power device measurement as a reference (mobile), as used by PageSpeed Insights.
const MAX_MOBILE_WIDTH = 420
const MAX_TABLET_WIDTH = 768
const MIN_NOTEBOOK_WIDTH = 1280

function useScreenResize() {
const [isMobile, setIsMobile] = useState(undefined)
const [isTablet, setIsTablet] = useState(undefined)
const [isDesktop, setIsDesktop] = useState(undefined)

useEffect(() => {
const handleResize = () => {
setIsMobile(window.innerWidth <= MAX_MOBILE_WIDTH)
setIsTablet(
window.innerWidth > MAX_MOBILE_WIDTH &&
window.innerWidth <= MAX_TABLET_WIDTH
)
setIsDesktop(window.innerWidth >= MIN_NOTEBOOK_WIDTH)
}

handleResize()

window.addEventListener('resize', handleResize)

return () => {
window.removeEventListener('resize', handleResize)
}
}, [])

return {
isMobile,
isTablet,
isDesktop,
loading:
isMobile === undefined ||
isTablet === undefined ||
isDesktop === undefined,
}
}

export default useScreenResize

0 comments on commit c94a768

Please sign in to comment.