From 437612f8b8c28fb384698c5c2b331e173cee8767 Mon Sep 17 00:00:00 2001
From: Fabio Berger <me@fabioberger.com>
Date: Wed, 3 Oct 2018 16:37:59 +0100
Subject: Use same Link UI component for react-scroll links

---
 packages/react-shared/src/components/link.tsx | 100 ++++++++++++++++++++++++++
 1 file changed, 100 insertions(+)
 create mode 100644 packages/react-shared/src/components/link.tsx

(limited to 'packages/react-shared/src/components/link.tsx')

diff --git a/packages/react-shared/src/components/link.tsx b/packages/react-shared/src/components/link.tsx
new file mode 100644
index 000000000..7425b9365
--- /dev/null
+++ b/packages/react-shared/src/components/link.tsx
@@ -0,0 +1,100 @@
+import * as _ from 'lodash';
+import * as React from 'react';
+import { Link as ReactRounterLink } from 'react-router-dom';
+import { Link as ScrollLink } from 'react-scroll';
+
+import { LinkType } from '../types';
+import { constants } from '../utils/constants';
+
+export interface LinkProps {
+    to: string;
+    type?: LinkType;
+    shouldOpenInNewTab?: boolean;
+    style?: React.CSSProperties;
+    className?: string;
+    onMouseOver?: (event: React.MouseEvent<HTMLElement>) => void;
+    onMouseLeave?: (event: React.MouseEvent<HTMLElement>) => void;
+    onMouseEnter?: (event: React.MouseEvent<HTMLElement>) => void;
+    containerId?: string;
+}
+
+/**
+ * A generic link component which let's the developer render internal & external links, and their associated
+ * behaviors with a single link component. Many times we want a menu including both internal & external links
+ * and this abstracts away the differences of rendering both types of links.
+ */
+export const Link: React.StatelessComponent<LinkProps> = ({
+    style,
+    className,
+    type,
+    to,
+    shouldOpenInNewTab,
+    children,
+    onMouseOver,
+    onMouseLeave,
+    onMouseEnter,
+    containerId,
+}) => {
+    const styleWithDefault = {
+        textDecoration: 'none',
+        ...style,
+    };
+
+    switch (type) {
+        case LinkType.External:
+            return (
+                <a
+                    target={shouldOpenInNewTab ? '_blank' : ''}
+                    className={className}
+                    style={styleWithDefault}
+                    href={to}
+                    onMouseOver={onMouseOver}
+                    onMouseEnter={onMouseEnter}
+                    onMouseLeave={onMouseLeave}
+                >
+                    {children}
+                </a>
+            );
+        case LinkType.ReactRoute:
+            return (
+                <ReactRounterLink
+                    to={to}
+                    className={className}
+                    style={styleWithDefault}
+                    target={shouldOpenInNewTab ? '_blank' : ''}
+                    onMouseOver={onMouseOver}
+                    onMouseEnter={onMouseEnter}
+                    onMouseLeave={onMouseLeave}
+                >
+                    {children}
+                </ReactRounterLink>
+            );
+        case LinkType.ReactScroll:
+            return (
+                <ScrollLink
+                    to={to}
+                    offset={0}
+                    hashSpy={true}
+                    duration={constants.DOCS_SCROLL_DURATION_MS}
+                    containerId={containerId}
+                >
+                    {children}
+                </ScrollLink>
+            );
+        default:
+            throw new Error(`Unrecognized LinkType: ${type}`);
+    }
+};
+
+Link.defaultProps = {
+    type: LinkType.ReactRoute,
+    shouldOpenInNewTab: false,
+    style: {},
+    className: '',
+    onMouseOver: _.noop.bind(_),
+    onMouseLeave: _.noop.bind(_),
+    onMouseEnter: _.noop.bind(_),
+    containerId: constants.DOCS_CONTAINER_ID,
+};
+
+Link.displayName = 'Link';
-- 
cgit v1.2.3


From 1bef42cdcb45e4614ffdc8d8a1e455b4fe970a45 Mon Sep 17 00:00:00 2001
From: Fabio Berger <me@fabioberger.com>
Date: Wed, 3 Oct 2018 17:17:16 +0100
Subject: Improve comment

---
 packages/react-shared/src/components/link.tsx | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

(limited to 'packages/react-shared/src/components/link.tsx')

diff --git a/packages/react-shared/src/components/link.tsx b/packages/react-shared/src/components/link.tsx
index 7425b9365..6200bfbd3 100644
--- a/packages/react-shared/src/components/link.tsx
+++ b/packages/react-shared/src/components/link.tsx
@@ -19,9 +19,10 @@ export interface LinkProps {
 }
 
 /**
- * A generic link component which let's the developer render internal & external links, and their associated
- * behaviors with a single link component. Many times we want a menu including both internal & external links
- * and this abstracts away the differences of rendering both types of links.
+ * A generic link component which let's the developer render internal, external and scroll-to-hash links, and
+ * their associated behaviors with a single link component. Many times we want a menu including a combination of
+ * internal, external and scroll links and the abstraction of the differences of rendering each types of link
+ * makes it much easier to do so.
  */
 export const Link: React.StatelessComponent<LinkProps> = ({
     style,
-- 
cgit v1.2.3


From 055763cceb9951b038b07488ddc7ae35210f1efe Mon Sep 17 00:00:00 2001
From: Fabio Berger <me@fabioberger.com>
Date: Fri, 5 Oct 2018 11:13:33 +0100
Subject: Fix bug where wiki links in dev dropdown weren't working when on the
 wiki

---
 packages/react-shared/src/components/link.tsx | 154 ++++++++++++++------------
 1 file changed, 82 insertions(+), 72 deletions(-)

(limited to 'packages/react-shared/src/components/link.tsx')

diff --git a/packages/react-shared/src/components/link.tsx b/packages/react-shared/src/components/link.tsx
index 6200bfbd3..7b22dc4fa 100644
--- a/packages/react-shared/src/components/link.tsx
+++ b/packages/react-shared/src/components/link.tsx
@@ -18,84 +18,94 @@ export interface LinkProps {
     containerId?: string;
 }
 
+export interface LinkState {}
+
 /**
  * A generic link component which let's the developer render internal, external and scroll-to-hash links, and
  * their associated behaviors with a single link component. Many times we want a menu including a combination of
  * internal, external and scroll links and the abstraction of the differences of rendering each types of link
  * makes it much easier to do so.
  */
-export const Link: React.StatelessComponent<LinkProps> = ({
-    style,
-    className,
-    type,
-    to,
-    shouldOpenInNewTab,
-    children,
-    onMouseOver,
-    onMouseLeave,
-    onMouseEnter,
-    containerId,
-}) => {
-    const styleWithDefault = {
-        textDecoration: 'none',
-        ...style,
+export class Link extends React.Component<LinkProps, LinkState> {
+    public static defaultProps: Partial<LinkProps> = {
+        type: LinkType.ReactRoute,
+        shouldOpenInNewTab: false,
+        style: {},
+        className: '',
+        onMouseOver: _.noop.bind(_),
+        onMouseLeave: _.noop.bind(_),
+        onMouseEnter: _.noop.bind(_),
+        containerId: constants.DOCS_CONTAINER_ID,
     };
-
-    switch (type) {
-        case LinkType.External:
-            return (
-                <a
-                    target={shouldOpenInNewTab ? '_blank' : ''}
-                    className={className}
-                    style={styleWithDefault}
-                    href={to}
-                    onMouseOver={onMouseOver}
-                    onMouseEnter={onMouseEnter}
-                    onMouseLeave={onMouseLeave}
-                >
-                    {children}
-                </a>
-            );
-        case LinkType.ReactRoute:
-            return (
-                <ReactRounterLink
-                    to={to}
-                    className={className}
-                    style={styleWithDefault}
-                    target={shouldOpenInNewTab ? '_blank' : ''}
-                    onMouseOver={onMouseOver}
-                    onMouseEnter={onMouseEnter}
-                    onMouseLeave={onMouseLeave}
-                >
-                    {children}
-                </ReactRounterLink>
-            );
-        case LinkType.ReactScroll:
-            return (
-                <ScrollLink
-                    to={to}
-                    offset={0}
-                    hashSpy={true}
-                    duration={constants.DOCS_SCROLL_DURATION_MS}
-                    containerId={containerId}
-                >
-                    {children}
-                </ScrollLink>
-            );
-        default:
-            throw new Error(`Unrecognized LinkType: ${type}`);
+    private _outerReactScrollSpan: HTMLSpanElement | null;
+    constructor(props: LinkProps) {
+        super(props);
+        this._outerReactScrollSpan = null;
     }
-};
-
-Link.defaultProps = {
-    type: LinkType.ReactRoute,
-    shouldOpenInNewTab: false,
-    style: {},
-    className: '',
-    onMouseOver: _.noop.bind(_),
-    onMouseLeave: _.noop.bind(_),
-    onMouseEnter: _.noop.bind(_),
-    containerId: constants.DOCS_CONTAINER_ID,
-};
+    public render(): React.ReactNode {
+        const styleWithDefault = {
+            textDecoration: 'none',
+            cursor: 'pointer',
+            ...this.props.style,
+        };
 
-Link.displayName = 'Link';
+        switch (this.props.type) {
+            case LinkType.External:
+                return (
+                    <a
+                        target={this.props.shouldOpenInNewTab ? '_blank' : ''}
+                        className={this.props.className}
+                        style={styleWithDefault}
+                        href={this.props.to}
+                        onMouseOver={this.props.onMouseOver}
+                        onMouseEnter={this.props.onMouseEnter}
+                        onMouseLeave={this.props.onMouseLeave}
+                    >
+                        {this.props.children}
+                    </a>
+                );
+            case LinkType.ReactRoute:
+                return (
+                    <ReactRounterLink
+                        to={this.props.to}
+                        className={this.props.className}
+                        style={styleWithDefault}
+                        target={this.props.shouldOpenInNewTab ? '_blank' : ''}
+                        onMouseOver={this.props.onMouseOver}
+                        onMouseEnter={this.props.onMouseEnter}
+                        onMouseLeave={this.props.onMouseLeave}
+                    >
+                        {this.props.children}
+                    </ReactRounterLink>
+                );
+            case LinkType.ReactScroll:
+                return (
+                    <span ref={input => (this._outerReactScrollSpan = input)}>
+                        <ScrollLink
+                            to={this.props.to}
+                            offset={0}
+                            hashSpy={true}
+                            duration={constants.DOCS_SCROLL_DURATION_MS}
+                            containerId={this.props.containerId}
+                            style={styleWithDefault}
+                        >
+                            <span onClick={this._onClickPropagateClickEventAroundScrollLink.bind(this)}>
+                                {this.props.children}
+                            </span>
+                        </ScrollLink>
+                    </span>
+                );
+            default:
+                throw new Error(`Unrecognized LinkType: ${this.props.type}`);
+        }
+    }
+    // HACK(fabio): For some reason, the react-scroll link decided to stop the propagation of click events.
+    // We do however rely on these events being propagated in certain scenarios (e.g when the link
+    // is within a dropdown we want to close upon being clicked). Because of this, we registry the
+    // click event of an inner span, and pass it around the react-scroll link to an outer span.
+    private _onClickPropagateClickEventAroundScrollLink(): void {
+        if (!_.isNull(this._outerReactScrollSpan)) {
+            this._outerReactScrollSpan.click();
+        }
+    }
+}
-- 
cgit v1.2.3


From e7de4b953fe8aaefee9c043679b021a485dc6dee Mon Sep 17 00:00:00 2001
From: Fabio Berger <me@fabioberger.com>
Date: Fri, 5 Oct 2018 11:51:52 +0100
Subject: Apply props to all link variants when possible

---
 packages/react-shared/src/components/link.tsx | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

(limited to 'packages/react-shared/src/components/link.tsx')

diff --git a/packages/react-shared/src/components/link.tsx b/packages/react-shared/src/components/link.tsx
index 7b22dc4fa..ee55cc642 100644
--- a/packages/react-shared/src/components/link.tsx
+++ b/packages/react-shared/src/components/link.tsx
@@ -80,13 +80,19 @@ export class Link extends React.Component<LinkProps, LinkState> {
                 );
             case LinkType.ReactScroll:
                 return (
-                    <span ref={input => (this._outerReactScrollSpan = input)}>
+                    <span
+                        ref={input => (this._outerReactScrollSpan = input)}
+                        onMouseOver={this.props.onMouseOver}
+                        onMouseEnter={this.props.onMouseEnter}
+                        onMouseLeave={this.props.onMouseLeave}
+                    >
                         <ScrollLink
                             to={this.props.to}
                             offset={0}
                             hashSpy={true}
                             duration={constants.DOCS_SCROLL_DURATION_MS}
                             containerId={this.props.containerId}
+                            className={this.props.className}
                             style={styleWithDefault}
                         >
                             <span onClick={this._onClickPropagateClickEventAroundScrollLink.bind(this)}>
-- 
cgit v1.2.3


From f7aee9c7a9df36e20888c10616a249c2a79ed749 Mon Sep 17 00:00:00 2001
From: Fabio Berger <me@fabioberger.com>
Date: Fri, 5 Oct 2018 12:00:24 +0100
Subject: Remove containerId option and throw if passing in shouldOpenInNewTab
 with type ReactScroll

---
 packages/react-shared/src/components/link.tsx | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

(limited to 'packages/react-shared/src/components/link.tsx')

diff --git a/packages/react-shared/src/components/link.tsx b/packages/react-shared/src/components/link.tsx
index ee55cc642..e8a13d506 100644
--- a/packages/react-shared/src/components/link.tsx
+++ b/packages/react-shared/src/components/link.tsx
@@ -6,7 +6,7 @@ import { Link as ScrollLink } from 'react-scroll';
 import { LinkType } from '../types';
 import { constants } from '../utils/constants';
 
-export interface LinkProps {
+interface LinkProps {
     to: string;
     type?: LinkType;
     shouldOpenInNewTab?: boolean;
@@ -15,7 +15,6 @@ export interface LinkProps {
     onMouseOver?: (event: React.MouseEvent<HTMLElement>) => void;
     onMouseLeave?: (event: React.MouseEvent<HTMLElement>) => void;
     onMouseEnter?: (event: React.MouseEvent<HTMLElement>) => void;
-    containerId?: string;
 }
 
 export interface LinkState {}
@@ -35,7 +34,6 @@ export class Link extends React.Component<LinkProps, LinkState> {
         onMouseOver: _.noop.bind(_),
         onMouseLeave: _.noop.bind(_),
         onMouseEnter: _.noop.bind(_),
-        containerId: constants.DOCS_CONTAINER_ID,
     };
     private _outerReactScrollSpan: HTMLSpanElement | null;
     constructor(props: LinkProps) {
@@ -43,6 +41,10 @@ export class Link extends React.Component<LinkProps, LinkState> {
         this._outerReactScrollSpan = null;
     }
     public render(): React.ReactNode {
+        if (this.props.type === LinkType.ReactScroll && this.props.shouldOpenInNewTab) {
+            throw new Error(`Cannot open LinkType.ReactScroll links in new tab. link.to: ${this.props.to}`);
+        }
+
         const styleWithDefault = {
             textDecoration: 'none',
             cursor: 'pointer',
@@ -91,7 +93,7 @@ export class Link extends React.Component<LinkProps, LinkState> {
                             offset={0}
                             hashSpy={true}
                             duration={constants.DOCS_SCROLL_DURATION_MS}
-                            containerId={this.props.containerId}
+                            containerId={constants.DOCS_CONTAINER_ID}
                             className={this.props.className}
                             style={styleWithDefault}
                         >
-- 
cgit v1.2.3


From e0355a2e395fc056fd1d5c5e1780784853546acd Mon Sep 17 00:00:00 2001
From: Fabio Berger <me@fabioberger.com>
Date: Fri, 5 Oct 2018 12:03:15 +0100
Subject: Rename scroll container

---
 packages/react-shared/src/components/link.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'packages/react-shared/src/components/link.tsx')

diff --git a/packages/react-shared/src/components/link.tsx b/packages/react-shared/src/components/link.tsx
index e8a13d506..51ffa1e1d 100644
--- a/packages/react-shared/src/components/link.tsx
+++ b/packages/react-shared/src/components/link.tsx
@@ -93,7 +93,7 @@ export class Link extends React.Component<LinkProps, LinkState> {
                             offset={0}
                             hashSpy={true}
                             duration={constants.DOCS_SCROLL_DURATION_MS}
-                            containerId={constants.DOCS_CONTAINER_ID}
+                            containerId={constants.SCROLL_CONTAINER_ID}
                             className={this.props.className}
                             style={styleWithDefault}
                         >
-- 
cgit v1.2.3


From 5f2cd33da07a7acc65f2e05acb35755f74af75a4 Mon Sep 17 00:00:00 2001
From: Fabio Berger <me@fabioberger.com>
Date: Fri, 5 Oct 2018 13:54:37 +0100
Subject: Remove style prop from Link

---
 packages/react-shared/src/components/link.tsx | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

(limited to 'packages/react-shared/src/components/link.tsx')

diff --git a/packages/react-shared/src/components/link.tsx b/packages/react-shared/src/components/link.tsx
index 51ffa1e1d..60891dd7a 100644
--- a/packages/react-shared/src/components/link.tsx
+++ b/packages/react-shared/src/components/link.tsx
@@ -10,11 +10,12 @@ interface LinkProps {
     to: string;
     type?: LinkType;
     shouldOpenInNewTab?: boolean;
-    style?: React.CSSProperties;
     className?: string;
     onMouseOver?: (event: React.MouseEvent<HTMLElement>) => void;
     onMouseLeave?: (event: React.MouseEvent<HTMLElement>) => void;
     onMouseEnter?: (event: React.MouseEvent<HTMLElement>) => void;
+    textDecoration?: string;
+    fontColor?: string;
 }
 
 export interface LinkState {}
@@ -29,11 +30,12 @@ export class Link extends React.Component<LinkProps, LinkState> {
     public static defaultProps: Partial<LinkProps> = {
         type: LinkType.ReactRoute,
         shouldOpenInNewTab: false,
-        style: {},
         className: '',
         onMouseOver: _.noop.bind(_),
         onMouseLeave: _.noop.bind(_),
         onMouseEnter: _.noop.bind(_),
+        textDecoration: 'none',
+        fontColor: 'inherit',
     };
     private _outerReactScrollSpan: HTMLSpanElement | null;
     constructor(props: LinkProps) {
@@ -46,11 +48,13 @@ export class Link extends React.Component<LinkProps, LinkState> {
         }
 
         const styleWithDefault = {
-            textDecoration: 'none',
+            textDecoration: this.props.textDecoration,
             cursor: 'pointer',
-            ...this.props.style,
+            color: this.props.fontColor,
         };
 
+        console.log('styleWithDefault', styleWithDefault);
+
         switch (this.props.type) {
             case LinkType.External:
                 return (
-- 
cgit v1.2.3


From fa6bd348992674192d07fef3d60950980212ecbb Mon Sep 17 00:00:00 2001
From: Fabio Berger <me@fabioberger.com>
Date: Fri, 5 Oct 2018 14:55:28 +0100
Subject: Remove type prop and instead infer it from the value of to

---
 packages/react-shared/src/components/link.tsx | 22 +++++++++++++++-------
 1 file changed, 15 insertions(+), 7 deletions(-)

(limited to 'packages/react-shared/src/components/link.tsx')

diff --git a/packages/react-shared/src/components/link.tsx b/packages/react-shared/src/components/link.tsx
index 60891dd7a..05ca93cc5 100644
--- a/packages/react-shared/src/components/link.tsx
+++ b/packages/react-shared/src/components/link.tsx
@@ -2,13 +2,13 @@ import * as _ from 'lodash';
 import * as React from 'react';
 import { Link as ReactRounterLink } from 'react-router-dom';
 import { Link as ScrollLink } from 'react-scroll';
+import * as validUrl from 'valid-url';
 
 import { LinkType } from '../types';
 import { constants } from '../utils/constants';
 
 interface LinkProps {
     to: string;
-    type?: LinkType;
     shouldOpenInNewTab?: boolean;
     className?: string;
     onMouseOver?: (event: React.MouseEvent<HTMLElement>) => void;
@@ -28,7 +28,6 @@ export interface LinkState {}
  */
 export class Link extends React.Component<LinkProps, LinkState> {
     public static defaultProps: Partial<LinkProps> = {
-        type: LinkType.ReactRoute,
         shouldOpenInNewTab: false,
         className: '',
         onMouseOver: _.noop.bind(_),
@@ -43,7 +42,18 @@ export class Link extends React.Component<LinkProps, LinkState> {
         this._outerReactScrollSpan = null;
     }
     public render(): React.ReactNode {
-        if (this.props.type === LinkType.ReactScroll && this.props.shouldOpenInNewTab) {
+        let type: LinkType;
+        const isReactRoute = _.startsWith(this.props.to, '/');
+        const isExternal = validUrl.isWebUri(this.props.to) || _.startsWith(this.props.to, 'mailto:');
+        if (isReactRoute) {
+            type = LinkType.ReactRoute;
+        } else if (isExternal) {
+            type = LinkType.External;
+        } else {
+            type = LinkType.ReactScroll;
+        }
+
+        if (type === LinkType.ReactScroll && this.props.shouldOpenInNewTab) {
             throw new Error(`Cannot open LinkType.ReactScroll links in new tab. link.to: ${this.props.to}`);
         }
 
@@ -53,9 +63,7 @@ export class Link extends React.Component<LinkProps, LinkState> {
             color: this.props.fontColor,
         };
 
-        console.log('styleWithDefault', styleWithDefault);
-
-        switch (this.props.type) {
+        switch (type) {
             case LinkType.External:
                 return (
                     <a
@@ -108,7 +116,7 @@ export class Link extends React.Component<LinkProps, LinkState> {
                     </span>
                 );
             default:
-                throw new Error(`Unrecognized LinkType: ${this.props.type}`);
+                throw new Error(`Unrecognized LinkType: ${type}`);
         }
     }
     // HACK(fabio): For some reason, the react-scroll link decided to stop the propagation of click events.
-- 
cgit v1.2.3


From 3ce665eeabb9fc75dd50847304242de096e54d46 Mon Sep 17 00:00:00 2001
From: Fabio Berger <me@fabioberger.com>
Date: Fri, 5 Oct 2018 17:58:22 +0100
Subject: Fix comment

---
 packages/react-shared/src/components/link.tsx | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'packages/react-shared/src/components/link.tsx')

diff --git a/packages/react-shared/src/components/link.tsx b/packages/react-shared/src/components/link.tsx
index 05ca93cc5..5a456109b 100644
--- a/packages/react-shared/src/components/link.tsx
+++ b/packages/react-shared/src/components/link.tsx
@@ -121,7 +121,7 @@ export class Link extends React.Component<LinkProps, LinkState> {
     }
     // HACK(fabio): For some reason, the react-scroll link decided to stop the propagation of click events.
     // We do however rely on these events being propagated in certain scenarios (e.g when the link
-    // is within a dropdown we want to close upon being clicked). Because of this, we registry the
+    // is within a dropdown we want to close upon being clicked). Because of this, we register the
     // click event of an inner span, and pass it around the react-scroll link to an outer span.
     private _onClickPropagateClickEventAroundScrollLink(): void {
         if (!_.isNull(this._outerReactScrollSpan)) {
-- 
cgit v1.2.3


From 0de654bbd52f7d4702cec9f1a9a5a2cbb793181b Mon Sep 17 00:00:00 2001
From: Fabio Berger <me@fabioberger.com>
Date: Fri, 19 Oct 2018 17:40:55 +0100
Subject: fix: scroll lag on doc reference and wiki pages by using react-scroll
 `spy` and only updating the sidebar menu items whose active state had changed

---
 packages/react-shared/src/components/link.tsx | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

(limited to 'packages/react-shared/src/components/link.tsx')

diff --git a/packages/react-shared/src/components/link.tsx b/packages/react-shared/src/components/link.tsx
index 5a456109b..089e6e2ba 100644
--- a/packages/react-shared/src/components/link.tsx
+++ b/packages/react-shared/src/components/link.tsx
@@ -7,7 +7,7 @@ import * as validUrl from 'valid-url';
 import { LinkType } from '../types';
 import { constants } from '../utils/constants';
 
-interface LinkProps {
+interface BaseLinkProps {
     to: string;
     shouldOpenInNewTab?: boolean;
     className?: string;
@@ -18,6 +18,12 @@ interface LinkProps {
     fontColor?: string;
 }
 
+interface ScrollLinkProps extends BaseLinkProps {
+    onActivityChanged?: (isActive: boolean) => void;
+}
+
+type LinkProps = BaseLinkProps & ScrollLinkProps;
+
 export interface LinkState {}
 
 /**
@@ -103,11 +109,14 @@ export class Link extends React.Component<LinkProps, LinkState> {
                         <ScrollLink
                             to={this.props.to}
                             offset={0}
+                            spy={true}
                             hashSpy={true}
                             duration={constants.DOCS_SCROLL_DURATION_MS}
                             containerId={constants.SCROLL_CONTAINER_ID}
                             className={this.props.className}
                             style={styleWithDefault}
+                            onSetActive={this._onActivityChanged.bind(this, true)}
+                            onSetInactive={this._onActivityChanged.bind(this, false)}
                         >
                             <span onClick={this._onClickPropagateClickEventAroundScrollLink.bind(this)}>
                                 {this.props.children}
@@ -119,6 +128,11 @@ export class Link extends React.Component<LinkProps, LinkState> {
                 throw new Error(`Unrecognized LinkType: ${type}`);
         }
     }
+    private _onActivityChanged(isActive: boolean): void {
+        if (this.props.onActivityChanged) {
+            this.props.onActivityChanged(isActive);
+        }
+    }
     // HACK(fabio): For some reason, the react-scroll link decided to stop the propagation of click events.
     // We do however rely on these events being propagated in certain scenarios (e.g when the link
     // is within a dropdown we want to close upon being clicked). Because of this, we register the
-- 
cgit v1.2.3

