diff --git a/content/tutorial/nav.yml b/content/tutorial/nav.yml index f3570cc9..adc5cf3a 100644 --- a/content/tutorial/nav.yml +++ b/content/tutorial/nav.yml @@ -1,6 +1,6 @@ - title: Tutorial items: - - id: tutorial + - id: before-we-start title: Before We Start href: /tutorial/tutorial.html#before-we-start forceInternal: true diff --git a/src/components/MarkdownPage/MarkdownPage.js b/src/components/MarkdownPage/MarkdownPage.js index a3145b86..56f62b10 100644 --- a/src/components/MarkdownPage/MarkdownPage.js +++ b/src/components/MarkdownPage/MarkdownPage.js @@ -26,6 +26,7 @@ const MarkdownPage = ({ authors, createLink, date, + enableScrollSync, ogDescription, location, markdownRemark, @@ -98,6 +99,7 @@ const MarkdownPage = ({
{ + const nextItemTopOffset = itemTopOffsets[i + 1]; + if (nextItemTopOffset) { + return ( + window.scrollY >= itemTopOffset.offsetTop && + window.scrollY < nextItemTopOffset.offsetTop + ); + } + return window.scrollY >= itemTopOffset.offsetTop; + }); + this.setState({ + activeItemId: item ? item.id : '', + }); + } + + render() { + const {activeItemId} = this.state; + return
; + } +} + +const _getItemIds = items => + items + .map(item => { + let subItemIds = []; + if (item.subitems) { + subItemIds = item.subitems.map(subitem => subitem.id); + } + return [item.id, ...subItemIds]; + }) + .reduce((prev, current) => prev.concat(current)); + +const _getElementTopOffsetsById = ids => + ids + .map(id => { + const element = document.getElementById(id); + if (!element) { + return null; + } + return { + id, + offsetTop: element.offsetTop, + }; + }) + .filter(item => item); + +export default ScrollSyncSection; diff --git a/src/templates/components/Sidebar/Section.js b/src/templates/components/Sidebar/Section.js index 7037f3b1..83b9917c 100644 --- a/src/templates/components/Sidebar/Section.js +++ b/src/templates/components/Sidebar/Section.js @@ -9,17 +9,16 @@ 'use strict'; -import React from 'react'; import {colors, media} from 'theme'; +import isItemActive from 'utils/isItemActive'; import MetaTitle from '../MetaTitle'; import ChevronSvg from '../ChevronSvg'; -// TODO Update isActive link as document scrolls past anchor tags -// Maybe used 'hashchange' along with 'scroll' to set/update active links - const Section = ({ + activeItemId, createLink, isActive, + isScrollSync, location, onLinkClick, onSectionTitleClick, @@ -67,6 +66,9 @@ const Section = ({ marginTop: 5, }}> {createLink({ + isActive: isScrollSync + ? activeItemId === item.id + : isItemActive(location, item), item, location, onLinkClick, @@ -78,6 +80,9 @@ const Section = ({ {item.subitems.map(subitem => (
  • {createLink({ + isActive: isScrollSync + ? activeItemId === subitem.id + : isItemActive(location, subitem), item: subitem, location, onLinkClick, diff --git a/src/templates/components/Sidebar/Sidebar.js b/src/templates/components/Sidebar/Sidebar.js index d94e2346..2f423303 100644 --- a/src/templates/components/Sidebar/Sidebar.js +++ b/src/templates/components/Sidebar/Sidebar.js @@ -12,6 +12,7 @@ import React, {Component} from 'react'; import Flex from 'components/Flex'; import Section from './Section'; +import ScrollSyncSection from './ScrollSyncSection'; import {media} from 'theme'; class Sidebar extends Component { @@ -24,9 +25,17 @@ class Sidebar extends Component { } render() { - const {closeParentMenu, createLink, location, sectionList} = this.props; + const { + closeParentMenu, + createLink, + enableScrollSync, + location, + sectionList, + } = this.props; const {activeSection} = this.state; + const SectionComponent = enableScrollSync ? ScrollSyncSection : Section; + return ( {sectionList.map((section, index) => ( -
    { return ( { - const isActive = isItemActive(location, item); - +const createLinkBlog = ({isActive, item, section}) => { return ( {isActive && } @@ -27,7 +24,7 @@ const createLinkBlog = ({item, location, section}) => { ); }; -const createLinkCommunity = ({item, location, section}) => { +const createLinkCommunity = ({isActive, item, section}) => { if (item.href) { return ( @@ -44,15 +41,13 @@ const createLinkCommunity = ({item, location, section}) => { ); } return createLinkDocs({ + isActive, item, - location, section, }); }; -const createLinkDocs = ({item, location, section}) => { - const isActive = isItemActive(location, item); - +const createLinkDocs = ({isActive, item, section}) => { return ( { ); }; -const createLinkTutorial = ({item, location, onLinkClick, section}) => { - const isActive = isItemActive(location, item); - +const createLinkTutorial = ({isActive, item, onLinkClick, section}) => { return (