| 33 | } |
| 34 | |
| 35 | class PageNav extends Component<RouteComponentProps, NavState> { |
| 36 | scrollSpy!: ScrollSpy; |
| 37 | state: NavState = { activeId: null, links: [] }; |
| 38 | componentDidMount() { |
| 39 | const { match } = this.props; |
| 40 | |
| 41 | // eslint-disable-next-line |
| 42 | this.setState({ links: store.getPageHeadings(match.path) }); |
| 43 | } |
| 44 | componentDidUpdate({ history, location }: RouteComponentProps) { |
| 45 | const { hash } = this.props.location; // old hash |
| 46 | const shouldRefresh = location.hash !== hash && history.action !== 'POP'; |
| 47 | |
| 48 | // this makes everything work, need those fresh nodes |
| 49 | if (shouldRefresh && this.scrollSpy.buildNodeList) { |
| 50 | this.scrollSpy.buildNodeList(); |
| 51 | } |
| 52 | } |
| 53 | getSelected = (ids: readonly (string | null)[]) => { |
| 54 | const activeId = ids[0]; |
| 55 | if (activeId !== this.state.activeId) { |
| 56 | this.setState({ activeId }); |
| 57 | } |
| 58 | }; |
| 59 | getScrollSpy: RefCallback<ScrollSpy> = (ref) => { |
| 60 | if (!ref) return; |
| 61 | this.scrollSpy = ref; |
| 62 | }; |
| 63 | handleItemClick = ({ |
| 64 | event, |
| 65 | hash, |
| 66 | }: { |
| 67 | readonly event: MouseEvent<HTMLDivElement>; |
| 68 | readonly hash: string; |
| 69 | }) => { |
| 70 | event.preventDefault(); |
| 71 | const path = `#${hash}`; |
| 72 | const el = document.querySelector<HTMLElement>(path); |
| 73 | const { history } = this.props; |
| 74 | |
| 75 | if (el && el.offsetTop) { |
| 76 | history.replace(path); |
| 77 | animatedScrollTo(window, el.offsetTop); |
| 78 | } |
| 79 | }; |
| 80 | render() { |
| 81 | const { activeId, links } = this.state; |
| 82 | const isSmallDevice = window.innerWidth <= 769; |
| 83 | |
| 84 | return links && links.length ? ( |
| 85 | <Sticky preserveHeight={isSmallDevice}> |
| 86 | <ScrollSpy ref={this.getScrollSpy} onChange={this.getSelected}> |
| 87 | <Nav> |
| 88 | {links.map((l) => { |
| 89 | const hash = l.path.slice(1); |
| 90 | const selected = hash === activeId; |
| 91 | |
| 92 | return l.level > 0 ? ( |
nothing calls this directly
no test coverage detected
searching dependent graphs…