Skip to content

Instantly share code, notes, and snippets.

@InputNeuron
Created August 9, 2020 22:34
Show Gist options
  • Select an option

  • Save InputNeuron/9e50c98bbf995f6a4a2fbee7902159ed to your computer and use it in GitHub Desktop.

Select an option

Save InputNeuron/9e50c98bbf995f6a4a2fbee7902159ed to your computer and use it in GitHub Desktop.
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