Fix bug where wiki links in dev dropdown weren't working when on the wiki
This commit is contained in:
@@ -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;
|
||||
}
|
||||
};
|
||||
public render(): React.ReactNode {
|
||||
const styleWithDefault = {
|
||||
textDecoration: 'none',
|
||||
cursor: 'pointer',
|
||||
...this.props.style,
|
||||
};
|
||||
|
||||
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';
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -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>
|
||||
|
@@ -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}
|
||||
|
Reference in New Issue
Block a user