{"size": 2143, "ext": "js", "max_stars_repo_path": "src/components/Layout.js", "max_stars_repo_name": "subhh/HOS-Metadata-Visualisation", "max_stars_repo_stars_event_min_datetime": "2022-02-04T09:22:45.000Z", "max_stars_repo_stars_event_max_datetime": "2022-02-04T09:22:45.000Z", "max_issues_repo_path": "src/components/Layout.js", "max_issues_repo_name": "subhh/HOS-Metadata-Visualisation", "max_issues_repo_issues_event_min_datetime": "2019-11-25T10:26:47.000Z", "max_issues_repo_issues_event_max_datetime": "2019-12-02T14:01:57.000Z", "max_forks_repo_path": "src/components/Layout.js", "max_forks_repo_name": "subhh/HOS-Metadata-Visualisation", "max_forks_repo_forks_event_min_datetime": null, "max_forks_repo_forks_event_max_datetime": null}
{"max_stars_count": 1, "max_issues_count": 1, "max_forks_count": null, "avg_line_length": 24.3522727273, "max_line_length": 86, "alphanum_fraction": 0.5846943537}
import React, { useState, useEffect } from 'react'
import { Spring } from 'react-spring/renderprops.cjs'
import { useTransition, animated } from 'react-spring'
import { Box } from 'rebass'
import { debounce } from 'lodash'

const headerHeightFallback = 130
const AnimatedBox = animated(Box)

/**
 * Main layout component, upper hero section can be expanded, content area is optional
 * and adapts to the hero.
 */
const Layout = ({
  expand,
  renderHero = x => null,
  renderContent = x => null,
}) => {
  const [width, setWidth] = useState(null)
  const [height, setHeight] = useState(null)

  useEffect(() => {
    // get header height from surrounding layout
    const nav = document.querySelector('#nav-primary')
    const header = document.querySelector('#header')
    let hh

    if (nav && header) {
      hh = nav.clientHeight + header.clientHeight + 24
    } else {
      hh = headerHeightFallback
    }

    const updateDimensions = () => {
      const width = window.innerWidth
      const height = expand ? window.innerHeight - hh : window.innerHeight * 0.4
      setWidth(width)
      setHeight(height)
    }

    updateDimensions()

    const debouncedHandleResize = debounce(updateDimensions, 200)

    window.addEventListener('resize', debouncedHandleResize)

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

  const statsToggleTransition = useTransition(!expand, null, {
    from: { opacity: 0 },
    enter: { opacity: 1 },
    leave: { opacity: 0 },
  })

  return (
    <>
      {height && (
        <Spring
          to={{
            height,
          }}
        >
          {({ height: currentHeight }) =>
            renderHero({
              width,
              height: Math.trunc(currentHeight),
              targetHeight: height,
            })
          }
        </Spring>
      )}
      {statsToggleTransition.map(
        ({ item: collapsed, key, props }) =>
          collapsed && (
            <AnimatedBox key={key} style={props}>
              {renderContent()}
            </AnimatedBox>
          )
      )}
    </>
  )
}

export default Layout
