Created
August 9, 2020 22:34
-
-
Save InputNeuron/9e50c98bbf995f6a4a2fbee7902159ed to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import React from 'react'; | |
| import {useLocation} from 'react-router-dom'; | |
| import {HashURLs} from "polar-shared/src/util/HashURLs"; | |
| import {IDStr} from "polar-shared/src/util/Strings"; | |
| interface IProps { | |
| readonly children: React.ForwardRefRenderFunction<HTMLDivElement, any>; | |
| // readonly children: React.ReactNode; | |
| } | |
| const ForwardRefComponent = React.forwardRef<HTMLDivElement>((props: any, ref) => { | |
| return <div ref={ref}>hello</div> | |
| }); | |
| const TestUsage = () => { | |
| return ( | |
| <> | |
| <ScrollIntoViewUsingLocation> | |
| <ForwardRefComponent/> | |
| </ScrollIntoViewUsingLocation> | |
| </> | |
| ); | |
| } | |
| /** | |
| * Simple component that takes a child, and then when we're given a param of | |
| * 'target=123' then we scroll to that component | |
| */ | |
| export const ScrollIntoViewUsingLocation = React.memo((props: IProps) => { | |
| const scrollTarget = useScrollTargetFromLocation(); | |
| const ref = React.useRef<HTMLElement>(); | |
| if (scrollTarget && ref.current) { | |
| const id = ref.current.getAttribute('id'); | |
| if (id !== scrollTarget) { | |
| // TODO: this component should take scrollIntoView opts and pass | |
| // them here. | |
| ref.current.scrollIntoView(); | |
| } | |
| } | |
| const Child = props.children; | |
| return ( | |
| <Child ref={ref}/> | |
| ); | |
| }) | |
| /** | |
| * The target of a scroll which should be a DOM ID. | |
| */ | |
| export type ScrollTarget = IDStr; | |
| namespace ScrollTargets { | |
| import QueryOrLocation = HashURLs.QueryOrLocation; | |
| export function parse(queryOrLocation: QueryOrLocation): ScrollTarget | undefined{ | |
| const params = HashURLs.parse(queryOrLocation); | |
| return params.get('target') || undefined; | |
| } | |
| } | |
| /** | |
| * Use location to parse the annotation. | |
| */ | |
| export function useScrollTargetFromLocation(): ScrollTarget | undefined { | |
| // TODO: I don't think this is cached across components... | |
| const location = useLocation(); | |
| return ScrollTargets.parse(location); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment