diff options
author | Fabio Berger <me@fabioberger.com> | 2018-10-05 18:13:33 +0800 |
---|---|---|
committer | Fabio Berger <me@fabioberger.com> | 2018-10-05 18:13:33 +0800 |
commit | 055763cceb9951b038b07488ddc7ae35210f1efe (patch) | |
tree | d91ff934b5a0ca0396ce453859aeefd058274ec1 | |
parent | 60ba8d57d45aedde7a08e4638215453f899b8e0d (diff) | |
download | dexon-sol-tools-055763cceb9951b038b07488ddc7ae35210f1efe.tar dexon-sol-tools-055763cceb9951b038b07488ddc7ae35210f1efe.tar.gz dexon-sol-tools-055763cceb9951b038b07488ddc7ae35210f1efe.tar.bz2 dexon-sol-tools-055763cceb9951b038b07488ddc7ae35210f1efe.tar.lz dexon-sol-tools-055763cceb9951b038b07488ddc7ae35210f1efe.tar.xz dexon-sol-tools-055763cceb9951b038b07488ddc7ae35210f1efe.tar.zst dexon-sol-tools-055763cceb9951b038b07488ddc7ae35210f1efe.zip |
Fix bug where wiki links in dev dropdown weren't working when on the wiki
-rw-r--r-- | packages/react-shared/src/components/link.tsx | 154 | ||||
-rw-r--r-- | packages/website/ts/components/dropdowns/developers_drop_down.tsx | 16 | ||||
-rw-r--r-- | packages/website/ts/components/top_bar/top_bar.tsx | 1 |
3 files changed, 93 insertions, 78 deletions
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(); + } + } +} diff --git a/packages/website/ts/components/dropdowns/developers_drop_down.tsx b/packages/website/ts/components/dropdowns/developers_drop_down.tsx index 6133c8b4d..ac1d82c75 100644 --- a/packages/website/ts/components/dropdowns/developers_drop_down.tsx +++ b/packages/website/ts/components/dropdowns/developers_drop_down.tsx @@ -64,6 +64,7 @@ const usefulLinksToLinkInfo: ALink[] = [ ]; interface DevelopersDropDownProps { + location: Location; translate: Translate; menuItemStyles: React.CSSProperties; menuIconStyle: React.CSSProperties; @@ -165,17 +166,20 @@ export class DevelopersDropDown extends React.Component<DevelopersDropDownProps, const numLinks = links.length; let i = 0; const renderLinks = _.map(links, (link: ALink) => { + const isWikiLink = _.startsWith(link.to, WebsitePaths.Wiki) && _.includes(link.to, '#'); + const isOnWiki = this.props.location.pathname === WebsitePaths.Wiki; + let to = link.to; + let type = link.type; + if (isWikiLink && isOnWiki) { + to = `${link.to.split('#')[1]}`; + type = LinkType.ReactScroll; + } i++; const isLast = i === numLinks; const linkText = this.props.translate.get(link.title as Key, Deco.Cap); return ( <div className={`pr1 pt1 ${!isLast && 'pb1'}`} key={`dev-dropdown-link-${link.title}`}> - <Link - to={link.to} - type={link.type} - shouldOpenInNewTab={!!link.shouldOpenInNewTab} - style={linkStyle} - > + <Link to={to} type={type} shouldOpenInNewTab={!!link.shouldOpenInNewTab} style={linkStyle}> {linkText} </Link> </div> diff --git a/packages/website/ts/components/top_bar/top_bar.tsx b/packages/website/ts/components/top_bar/top_bar.tsx index e25c0a0f7..d05b72d98 100644 --- a/packages/website/ts/components/top_bar/top_bar.tsx +++ b/packages/website/ts/components/top_bar/top_bar.tsx @@ -161,6 +161,7 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> { <div className={menuClasses}> <div className="flex items-center justify-between"> <DevelopersDropDown + location={this.props.location} menuItemStyles={styles.menuItem} translate={this.props.translate} menuIconStyle={menuIconStyle} |