diff options
author | Fabio Berger <me@fabioberger.com> | 2018-10-03 23:37:59 +0800 |
---|---|---|
committer | Fabio Berger <me@fabioberger.com> | 2018-10-03 23:37:59 +0800 |
commit | 437612f8b8c28fb384698c5c2b331e173cee8767 (patch) | |
tree | 5f182d44c0fa3bc2e29667d9b12e58b1cd2542d1 /packages/react-shared/src/components/link.tsx | |
parent | ab855cdd1cfa2e4fcc45499508dca9c9e8733b61 (diff) | |
download | dexon-sol-tools-437612f8b8c28fb384698c5c2b331e173cee8767.tar dexon-sol-tools-437612f8b8c28fb384698c5c2b331e173cee8767.tar.gz dexon-sol-tools-437612f8b8c28fb384698c5c2b331e173cee8767.tar.bz2 dexon-sol-tools-437612f8b8c28fb384698c5c2b331e173cee8767.tar.lz dexon-sol-tools-437612f8b8c28fb384698c5c2b331e173cee8767.tar.xz dexon-sol-tools-437612f8b8c28fb384698c5c2b331e173cee8767.tar.zst dexon-sol-tools-437612f8b8c28fb384698c5c2b331e173cee8767.zip |
Use same Link UI component for react-scroll links
Diffstat (limited to 'packages/react-shared/src/components/link.tsx')
-rw-r--r-- | packages/react-shared/src/components/link.tsx | 100 |
1 files changed, 100 insertions, 0 deletions
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'; |