| | import { useState, useEffect } from 'react' |
| | import cx from 'classnames' |
| | import { ChevronUpIcon } from '@primer/octicons-react' |
| |
|
| | import styles from './ScrollButton.module.scss' |
| |
|
| | const { transition200, opacity0, opacity100, customFocus } = styles |
| |
|
| | export type ScrollButtonPropsT = { |
| | className?: string |
| | ariaLabel?: string |
| | } |
| |
|
| | export const ScrollButton = ({ className, ariaLabel }: ScrollButtonPropsT) => { |
| | const [show, setShow] = useState(false) |
| | const [isTallEnough, setIsTallEnough] = useState(false) |
| |
|
| | useEffect(() => { |
| | |
| | |
| | |
| | const h1Element = document.getElementsByTagName('h1')[0] |
| | if (!h1Element) { |
| | if (process.env.NODE_ENV !== 'production') { |
| | throw new Error('No h1 element found in the document.') |
| | } |
| | return |
| | } |
| |
|
| | const observer = new IntersectionObserver( |
| | function (entries) { |
| | if (entries[0].isIntersecting === false) { |
| | setShow(true) |
| | } else { |
| | setShow(false) |
| | } |
| | }, |
| | { threshold: [0] }, |
| | ) |
| | observer.observe(h1Element) |
| | return () => { |
| | observer.disconnect() |
| | } |
| | }, []) |
| |
|
| | |
| | |
| | useEffect(() => { |
| | function updateDocumentSize() { |
| | setIsTallEnough(document.documentElement.clientHeight > 400) |
| | } |
| | updateDocumentSize() |
| | window.addEventListener('resize', updateDocumentSize) |
| | return () => window.removeEventListener('resize', updateDocumentSize) |
| | }, []) |
| |
|
| | const onClick = () => { |
| | document?.getElementById('github-logo')?.focus() |
| | document?.getElementById('main-content')?.scrollIntoView() |
| | } |
| |
|
| | return ( |
| | <div |
| | role="tooltip" |
| | className={cx(className, transition200, show && isTallEnough ? opacity100 : opacity0)} |
| | > |
| | <button |
| | onClick={onClick} |
| | className={cx( |
| | 'ghd-scroll-to-top', // for data tracking, see events.ts |
| | 'tooltipped tooltipped-n tooltipped-no-delay btn circle border-1', |
| | 'd-flex flex-items-center flex-justify-center', |
| | customFocus, |
| | styles.scrollButton, |
| | )} |
| | aria-label={ariaLabel} |
| | > |
| | <ChevronUpIcon /> |
| | </button> |
| | </div> |
| | ) |
| | } |
| |
|