diff options
Diffstat (limited to 'src/components/ui/Link.tsx')
-rw-r--r-- | src/components/ui/Link.tsx | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/src/components/ui/Link.tsx b/src/components/ui/Link.tsx new file mode 100644 index 000000000..b5890ebd1 --- /dev/null +++ b/src/components/ui/Link.tsx | |||
@@ -0,0 +1,73 @@ | |||
1 | import { Component, CSSProperties, ReactNode, MouseEvent } from 'react'; | ||
2 | import { inject, observer } from 'mobx-react'; | ||
3 | import classnames from 'classnames'; | ||
4 | import matchRoute from '../../helpers/routing-helpers'; | ||
5 | import { openExternalUrl } from '../../helpers/url-helpers'; | ||
6 | import { StoresProps } from '../../@types/ferdium-components.types'; | ||
7 | |||
8 | interface IProps extends Partial<StoresProps> { | ||
9 | children: ReactNode; | ||
10 | to: string; | ||
11 | className?: string; | ||
12 | activeClassName?: string; | ||
13 | strictFilter?: boolean; | ||
14 | target?: string; | ||
15 | style?: CSSProperties; | ||
16 | disabled?: boolean; | ||
17 | } | ||
18 | |||
19 | // TODO: create container component for this component | ||
20 | @inject('stores') | ||
21 | @observer | ||
22 | class Link extends Component<IProps> { | ||
23 | constructor(props: IProps) { | ||
24 | super(props); | ||
25 | } | ||
26 | |||
27 | onClick(e: MouseEvent<HTMLAnchorElement>): void { | ||
28 | const { disabled = false, target = '', to } = this.props; | ||
29 | if (disabled) { | ||
30 | e.preventDefault(); | ||
31 | } else if (target === '_blank') { | ||
32 | e.preventDefault(); | ||
33 | openExternalUrl(to, true); | ||
34 | } | ||
35 | // Note: if neither of the above, then let the other onClick handlers process it | ||
36 | } | ||
37 | |||
38 | render() { | ||
39 | const { | ||
40 | children, | ||
41 | stores, | ||
42 | to, | ||
43 | className = '', | ||
44 | activeClassName = '', | ||
45 | strictFilter = false, | ||
46 | disabled = false, | ||
47 | style = {}, | ||
48 | } = this.props; | ||
49 | const { router } = stores!; | ||
50 | |||
51 | const filter = strictFilter ? `${to}` : `${to}(*action)`; | ||
52 | const match = matchRoute(filter, router.location.pathname); | ||
53 | |||
54 | const linkClasses = classnames({ | ||
55 | [`${className}`]: true, | ||
56 | [`${activeClassName}`]: match, | ||
57 | 'is-disabled': disabled, | ||
58 | }); | ||
59 | |||
60 | return ( | ||
61 | <a | ||
62 | href={router.history.createHref(to)} | ||
63 | className={linkClasses} | ||
64 | style={style} | ||
65 | onClick={e => this.onClick(e)} | ||
66 | > | ||
67 | {children} | ||
68 | </a> | ||
69 | ); | ||
70 | } | ||
71 | } | ||
72 | |||
73 | export default Link; | ||