/
DefaultNavbarItem.tsx
126 lines (116 loc) · 3.23 KB
/
DefaultNavbarItem.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import React from 'react';
import clsx from 'clsx';
import Link from '@docusaurus/Link';
import useBaseUrl from '@docusaurus/useBaseUrl';
import type {
NavLinkProps,
DesktopOrMobileNavBarItemProps,
Props,
} from '@theme/NavbarItem/DefaultNavbarItem';
import IconExternalLink from '@theme/IconExternalLink';
import isInternalUrl from '@docusaurus/isInternalUrl';
import {isRegexpStringMatch} from '@docusaurus/theme-common';
import {getInfimaActiveClassName} from './index';
const dropdownLinkActiveClass = 'dropdown__link--active';
export function NavLink({
activeBasePath,
activeBaseRegex,
to,
href,
label,
activeClassName = '',
prependBaseUrlToHref,
...props
}: NavLinkProps): JSX.Element {
// TODO all this seems hacky
// {to: 'version'} should probably be forbidden, in favor of {to: '/version'}
const toUrl = useBaseUrl(to);
const activeBaseUrl = useBaseUrl(activeBasePath);
const normalizedHref = useBaseUrl(href, {forcePrependBaseUrl: true});
const isExternalLink = label && href && !isInternalUrl(href);
const isDropdownLink = activeClassName === dropdownLinkActiveClass;
return (
<Link
{...(href
? {
href: prependBaseUrlToHref ? normalizedHref : href,
}
: {
isNavLink: true,
activeClassName: !props.className?.includes(activeClassName)
? activeClassName
: '',
to: toUrl,
...(activeBasePath || activeBaseRegex
? {
isActive: (_match, location) =>
activeBaseRegex
? isRegexpStringMatch(activeBaseRegex, location.pathname)
: location.pathname.startsWith(activeBaseUrl),
}
: null),
})}
{...props}>
{isExternalLink ? (
<span>
{label}
<IconExternalLink {...(isDropdownLink && {width: 12, height: 12})} />
</span>
) : (
label
)}
</Link>
);
}
function DefaultNavbarItemDesktop({
className,
isDropdownItem = false,
...props
}: DesktopOrMobileNavBarItemProps) {
const element = (
<NavLink
className={clsx(
isDropdownItem ? 'dropdown__link' : 'navbar__item navbar__link',
className,
)}
{...props}
/>
);
if (isDropdownItem) {
return <li>{element}</li>;
}
return element;
}
function DefaultNavbarItemMobile({
className,
isDropdownItem: _isDropdownItem,
...props
}: DesktopOrMobileNavBarItemProps) {
return (
<li className="menu__list-item">
<NavLink className={clsx('menu__link', className)} {...props} />
</li>
);
}
function DefaultNavbarItem({
mobile = false,
position: _position, // Need to destructure position from props so that it doesn't get passed on.
...props
}: Props): JSX.Element {
const Comp = mobile ? DefaultNavbarItemMobile : DefaultNavbarItemDesktop;
return (
<Comp
{...props}
activeClassName={
props.activeClassName ?? getInfimaActiveClassName(mobile)
}
/>
);
}
export default DefaultNavbarItem;