Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Commit

Permalink
Refactor withScrollToTop to remove useCallback and use typescript
Browse files Browse the repository at this point in the history
  • Loading branch information
mikejolley committed Jul 21, 2021
1 parent 0905b40 commit e62c42b
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 83 deletions.
83 changes: 0 additions & 83 deletions assets/js/base/hocs/with-scroll-to-top/index.js

This file was deleted.

77 changes: 77 additions & 0 deletions assets/js/base/hocs/with-scroll-to-top/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/**
* External dependencies
*/
import { useRef } from '@wordpress/element';

/**
* Internal dependencies
*/
import './style.scss';

interface ScrollToTopProps {
focusableSelector?: string;
}

const maybeScrollToTop = ( scrollPoint: HTMLElement ): void => {
const yPos = scrollPoint.getBoundingClientRect().bottom;
const isScrollPointVisible = yPos >= 0 && yPos <= window.innerHeight;

if ( ! isScrollPointVisible ) {
scrollPoint.scrollIntoView();
}
};

const moveFocusToTop = (
scrollPoint: HTMLElement,
focusableSelector: string
): void => {
const focusableElements =
scrollPoint.parentElement?.querySelectorAll( focusableSelector ) || [];

if ( focusableElements.length ) {
( focusableElements[ 0 ] as HTMLElement )?.focus();
}
};

const scrollToHTMLElement = (
scrollPoint: HTMLElement,
{ focusableSelector }: ScrollToTopProps
): void => {
if ( ! window || ! Number.isFinite( window.innerHeight ) ) {
return;
}

maybeScrollToTop( scrollPoint );

if ( focusableSelector ) {
moveFocusToTop( scrollPoint, focusableSelector );
}
};

/**
* HOC that provides a function to scroll to the top of the component.
*/
const withScrollToTop = (
OriginalComponent: React.FunctionComponent< Record< string, unknown > >
) => {
return ( props: Record< string, unknown > ): JSX.Element => {
const scrollPointRef = useRef< HTMLDivElement >( null );
const scrollToTop = ( args: ScrollToTopProps ) => {
if ( scrollPointRef.current !== null ) {
scrollToHTMLElement( scrollPointRef.current, args );
}
};
return (
<>
<div
className="with-scroll-to-top__scroll-point"
ref={ scrollPointRef }
aria-hidden
/>
<OriginalComponent { ...props } scrollToTop={ scrollToTop } />
</>
);
};
};

export default withScrollToTop;

0 comments on commit e62c42b

Please sign in to comment.