1
0
Fork 1
mirror of https://github.com/thatmattlove/hyperglass.git synced 2026-01-17 08:48:05 +00:00

update docusaurus

This commit is contained in:
checktheroads 2020-07-17 00:54:35 -07:00
parent a1d6754351
commit 840484185e
15 changed files with 2024 additions and 410 deletions

View file

@ -2,7 +2,7 @@ const githubURL = "https://github.com/checktheroads/hyperglass";
const { googleTrackingId, algoliaKey } = process.env;
module.exports = {
const docusaurusConfig = {
title: "hyperglass",
tagline: "the network looking glass that tries to make the internet better.",
url: "https://hyperglass.io",
@ -17,7 +17,7 @@ module.exports = {
anonymizeIP: false,
},
algolia: {
apiKey: algoliaKey,
apiKey: algoliaKey || "dev",
indexName: "hyperglass",
},
navbar: {
@ -48,7 +48,7 @@ module.exports = {
},
{
label: "Configuration",
to: "docs/configuration",
to: "docs/parameters",
},
],
},
@ -91,7 +91,7 @@ module.exports = {
{
docs: {
sidebarPath: require.resolve("./sidebars.js"),
editUrl: githubURL + "/edit/master/docs/",
editUrl: githubURL + "/edit/v1.0.0/docs/",
},
theme: {
customCss: require.resolve("./src/css/custom.css"),
@ -99,8 +99,7 @@ module.exports = {
},
],
],
plugins: [
"@docusaurus/plugin-google-analytics",
require("./generateSitemap"),
],
plugins: ["@docusaurus/plugin-google-analytics"],
};
module.exports = docusaurusConfig;

View file

@ -9,9 +9,8 @@
"deploy": "docusaurus deploy"
},
"dependencies": {
"@docusaurus/core": "^2.0.0-alpha.50",
"@docusaurus/plugin-sitemap": "^2.0.0-alpha.50",
"@docusaurus/preset-classic": "^2.0.0-alpha.50",
"@docusaurus/core": "^2.0.0-alpha.58",
"@docusaurus/preset-classic": "^2.0.0-alpha.58",
"classnames": "^2.2.6",
"globby": "^11.0.1",
"prismjs": "^1.19.0",

View file

@ -44,29 +44,37 @@
:root {
--ifm-menu-color-active: black;
--ra-color-link: var(--ifm-color-black);
--ra-color-caution: var(--ifm-color-warning-lightest);
--ra-color-tip: var(--ifm-color-success-lightest);
--ra-color-important: var(--ifm-color-info-lightest);
--ra-color-note: var(--ifm-color-gray-200);
--ra-color-warning: var(--ifm-color-danger-lighter);
--ra-admonition-color: var(--ifm-font-base-color);
--ifm-alert-background-color: var(--ifm-color-gray-400);
}
html[data-theme="dark"]:root {
--ifm-background-color: #121212;
--ifm-background-surface-color: #1e2125;
--ifm-navbar-background-color: var(--ifm-background-color);
--ifm-menu-color-active: var(--ifm-color-primary);
--ra-color-link: var(--ifm-color-black);
--ra-color-caution: var(--ifm-color-warning-darkest);
--ra-color-tip: var(--ifm-color-success-darkest);
--ra-color-important: var(--ifm-color-info-darkest);
--ra-color-note: var(--ifm-color-gray-600);
--ra-color-warning: var(--ifm-color-danger-darker);
--ifm-blockquote-color: var(--ifm-color-emphasis-400);
}
.admonition.alert {
--ra-admonition-icon-color: currentColor;
--ifm-alert-color: var(--ifm-font-color-base);
border-color: unset;
border-style: unset;
border-width: unset;
box-shadow: var(--ifm-global-shadow-md);
}
html[data-theme="dark"] .admonition.alert--warning {
--ifm-alert-color: var(--ifm-color-black);
}
html[data-theme="dark"] .admonition.alert--critical {
--ifm-alert-color: var(--ifm-color-black);
}
html[data-theme="dark"] .admonition.alert--info {
--ifm-alert-color: var(--ifm-color-black);
}
html[data-theme=""] .admonition.alert--success {
--ifm-alert-color: white;
}
html[data-theme="dark"]:root .admonition.alert.admonition-note {
@ -78,6 +86,11 @@ html[data-theme="dark"]:root .admonition.alert.admonition-note {
--ifm-alert-color: var(--ifm-color-black);
}
.admonition.alert.admonition-note[class] .admonition-content[class] a {
color: var(--ifm-font-color-base);
opacity: 0.9;
}
html[data-theme="dark"] .footer.footer--dark {
--ifm-footer-color: var(--ifm-color-emphasis-400);
--ifm-navbar-background-color: var(--ifm-background-color);
@ -126,12 +139,16 @@ html[data-theme="dark"] {
}
.docusaurus-highlight-code-line {
background-color: rgb(72, 77, 91);
background-color: rgba(0, 0, 0, 0.1);
display: block;
margin: 0 calc(-1 * var(--ifm-pre-padding));
padding: 0 var(--ifm-pre-padding);
}
html[data-theme="dark"] .docusaurus-highlight-code-line {
background-color: rgba(255, 255, 255, 0.1);
}
table {
margin-top: var(--ifm-spacing-vertical);
}
@ -215,6 +232,20 @@ html[data-theme="dark"] .navbar .navbar__items a.navbar__brand {
}
}
.menu .menu__link.menu__link--active {
.menu .menu__list .menu__list-item .menu__link.menu__link--active {
font-weight: var(--ifm-font-weight-bold);
color: var(--ifm-color-secondary);
}
html[data-theme="dark"]
.menu
.menu__list
.menu__list-item
.menu__link.menu__link--active {
color: var(--ifm-color-primary);
}
.menu .menu__list .menu__list-item .menu__link,
.table-of-contents .table-of-contents__link {
color: var(--ifm-font-color-base);
}

View file

@ -53,7 +53,7 @@ h2.smallerTitle[class] {
}
.homeBtn:hover {
color: unset !important;
color: white !important;
}
.btnPrimary:hover {

View file

@ -7,7 +7,7 @@ export default {
},
styles: [
{
types: ["boolean", "number"],
types: ["boolean", "number", "null"],
style: {
color: "rgb(189, 147, 249)",
},
@ -88,5 +88,13 @@ export default {
color: "rgb(241, 250, 140)",
},
},
{
types: ["important"],
style: {
color: "rgb(80, 250, 123)",
fontStyle: "italic",
textDecoration: "underline",
},
},
],
};

View file

@ -0,0 +1,84 @@
// Original: https://raw.githubusercontent.com/PrismJS/prism-themes/master/themes/prism-ghcolors.css
var theme = {
plain: {
color: "#393A34",
backgroundColor: "#f6f8fa",
},
styles: [
{
types: ["comment", "prolog", "doctype", "cdata"],
style: {
color: "#999988",
fontStyle: "italic",
},
},
{
types: ["namespace"],
style: {
opacity: 0.7,
},
},
{
types: ["string", "attr-value"],
style: {
color: "#e3116c",
},
},
{
types: ["punctuation", "operator"],
style: {
color: "#393A34",
},
},
{
types: [
"entity",
"url",
"symbol",
"number",
"boolean",
"variable",
"constant",
"property",
"regex",
"inserted",
],
style: {
color: "#36acaa",
},
},
{
types: ["atrule", "keyword", "attr-name", "selector"],
style: {
color: "#00a4db",
},
},
{
types: ["function", "deleted", "tag"],
style: {
color: "#d73a49",
},
},
{
types: ["function-variable"],
style: {
color: "#6f42c1",
},
},
{
types: ["tag", "selector", "keyword"],
style: {
color: "#00009f",
},
},
{
types: ["important"],
style: {
color: "#d73a49",
fontStyle: "italic",
},
},
],
};
export default theme;

View file

@ -11,7 +11,8 @@ import React, { useEffect, useState, useRef } from "react";
import classnames from "classnames";
import Highlight, { defaultProps } from "prism-react-renderer";
import Prism from "prism-react-renderer/prism";
import defaultTheme from "./dracula";
import darkTheme from "./dracula";
import lightTheme from "./github";
import Clipboard from "clipboard";
import rangeParser from "parse-numeric-range";
import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
@ -118,8 +119,8 @@ export default ({ children, className: languageClassName, metastring }) => {
let codeBlockTitle = "";
const { isDarkTheme } = useThemeContext();
const lightModeTheme = prism.theme || defaultTheme;
const darkModeTheme = prism.darkTheme || lightModeTheme;
const lightModeTheme = prism.theme || lightTheme || darkTheme;
const darkModeTheme = prism.darkTheme || darkTheme || lightTheme;
const prismTheme = isDarkTheme ? darkModeTheme : lightModeTheme;
if (metastring && highlightLinesRangeRegex.test(metastring)) {

View file

@ -17,7 +17,7 @@ function FooterLink({ to, href, label, ...props }) {
const toUrl = useBaseUrl(to);
return (
<Link
className="footer__link-item"
className={classnames(styles.footerLink, "footer__link-item")}
{...(href
? {
target: "_blank",

View file

@ -6,22 +6,30 @@
*/
.footerLogoLink {
opacity: 0.5;
transition: opacity 0.15s ease-in-out;
opacity: 0.5;
transition: opacity 0.15s ease-in-out;
}
.footerLogoLink:hover {
opacity: 1;
opacity: 1;
}
.footerCol:first-child {
text-align: left;
text-align: left;
}
.footerCol:not(:first-child):not(:last-child) {
text-align: center;
text-align: center;
}
.footerCol:last-child {
text-align: right;
text-align: right;
}
html[data-theme="dark"] .footerLink[class] {
color: var(--ifm-color-emphasis-400);
}
.footerLink[class] {
color: var(--ifm-color-emphasis-700);
}

View file

@ -7,15 +7,14 @@
import React from "react";
import Head from "@docusaurus/Head";
import isInternalUrl from "@docusaurus/isInternalUrl";
import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
import useBaseUrl from "@docusaurus/useBaseUrl";
import ThemeProvider from "@theme/ThemeProvider";
import TabGroupChoiceProvider from "@theme/TabGroupChoiceProvider";
import UserPreferencesProvider from "@theme/UserPreferencesProvider";
import AnnouncementBar from "@theme/AnnouncementBar";
import Navbar from "@theme/Navbar";
import Footer from "@theme/Footer";
import Navbar from "../Navbar";
import Footer from "../Footer";
import "./styles.css";
@ -38,22 +37,14 @@ function Layout(props) {
version,
} = props;
const metaTitle = title ? `${title} | ${siteTitle}` : siteTitle;
const metaImage = image || defaultImage;
let metaImageUrl = siteUrl + useBaseUrl(metaImage);
if (!isInternalUrl(metaImage)) {
metaImageUrl = metaImage;
}
const metaImageUrl = useBaseUrl(metaImage, { absolute: true });
const faviconUrl = useBaseUrl(favicon);
return (
<ThemeProvider>
<TabGroupChoiceProvider>
<UserPreferencesProvider>
<Head>
{/* TODO: Do not assume that it is in english language */}
<html lang="en" />
{metaTitle && <title>{metaTitle}</title>}
{metaTitle && <meta property="og:title" content={metaTitle} />}
{favicon && <link rel="shortcut icon" href={faviconUrl} />}
@ -66,24 +57,25 @@ function Layout(props) {
<meta name="keywords" content={keywords.join(",")} />
)}
{metaImage && <meta property="og:image" content={metaImageUrl} />}
{metaImage && <meta property="og:image:width" content="1200" />}
{metaImage && <meta property="og:image:height" content="630" />}
{metaImage && (
<meta property="twitter:image" content={metaImageUrl} />
)}
{metaImage && (
<meta name="twitter:image:alt" content={`Image for ${metaTitle}`} />
)}
{metaImage && <meta property="og:image:width" content="1200" />}
{metaImage && <meta property="og:image:height" content="630" />}
{permalink && (
<meta property="og:url" content={siteUrl + permalink} />
)}
{permalink && <link rel="canonical" href={siteUrl + permalink} />}
<meta name="twitter:card" content="summary_large_image" />
</Head>
<AnnouncementBar />
<Navbar />
<div className="main-wrapper">{children}</div>
{!noFooter && <Footer />}
</TabGroupChoiceProvider>
</UserPreferencesProvider>
</ThemeProvider>
);
}

View file

@ -1,42 +1,65 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
* 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, { useCallback, useState } from "react";
import classnames from "classnames";
import React, { useCallback, useState, useEffect } from "react";
import clsx from "clsx";
import Link from "@docusaurus/Link";
import { useLocation } from "react-router-dom";
import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
import useBaseUrl from "@docusaurus/useBaseUrl";
import SearchBar from "@theme/SearchBar";
import SearchBar from "../SearchBar";
import useThemeContext from "@theme/hooks/useThemeContext";
import useHideableNavbar from "@theme/hooks/useHideableNavbar";
import useLockBodyScroll from "@theme/hooks/useLockBodyScroll";
import useWindowSize, { windowSizes } from "@theme/hooks/useWindowSize";
import useLogo from "@theme/hooks/useLogo";
import useMedia from "use-media";
import { ColorModeToggle } from "../../components/ColorModeToggle";
import { GithubButton } from "../../components/GithubButton";
import Logo from "../../components/Logo";
import styles from "./styles.module.css";
function NavLink({ to, href, label, position, ...props }) {
// retrocompatible with v1
const DefaultNavItemPosition = "right";
function NavLink({
activeBasePath,
activeBaseRegex,
to,
href,
label,
activeClassName = "navbar__link--active",
prependBaseUrlToHref,
...props
}) {
const toUrl = useBaseUrl(to);
const activeBaseUrl = useBaseUrl(activeBasePath);
const normalizedHref = useBaseUrl(href, { forcePrependBaseUrl: true });
return (
<Link
className={classnames(styles.navLink, "navbar__item navbar__link")}
{...(href
? {
target: "_blank",
rel: "noopener noreferrer",
href,
href: prependBaseUrlToHref ? normalizedHref : href,
}
: {
activeClassName: "navbar__link--active",
isNavLink: true,
activeClassName,
to: toUrl,
...(activeBasePath || activeBaseRegex
? {
isActive: (_match, location) =>
activeBaseRegex
? new RegExp(activeBaseRegex).test(location.pathname)
: location.pathname.startsWith(activeBaseUrl),
}
: null),
})}
{...props}
>
@ -45,21 +68,137 @@ function NavLink({ to, href, label, position, ...props }) {
);
}
function Navbar() {
const context = useDocusaurusContext();
const { siteConfig = {} } = context;
const { baseUrl, themeConfig = {} } = siteConfig;
const { navbar = {}, disableDarkMode = false } = themeConfig;
const { title, logo = {}, links = [], hideOnScroll = false } = navbar;
function NavItem({
items,
position = DefaultNavItemPosition,
className,
...props
}) {
const navLinkClassNames = (extraClassName, isDropdownItem = false) =>
clsx(
styles.navLink,
{
"navbar__item navbar__link": !isDropdownItem,
dropdown__link: isDropdownItem,
},
extraClassName
);
if (!items) {
return <NavLink className={navLinkClassNames(className)} {...props} />;
}
return (
<div
className={clsx("navbar__item", "dropdown", "dropdown--hoverable", {
"dropdown--left": position === "left",
"dropdown--right": position === "right",
})}
>
<NavLink
className={navLinkClassNames(className)}
{...props}
onClick={(e) => e.preventDefault()}
onKeyDown={(e) => {
if (e.key === "Enter") {
e.target.parentNode.classList.toggle("dropdown--show");
}
}}
>
{props.label}
</NavLink>
<ul className="dropdown__menu">
{items.map(
({ className: childItemClassName, ...childItemProps }, i) => (
<li key={i}>
<NavLink
activeClassName="dropdown__link--active"
className={navLinkClassNames(childItemClassName, true)}
{...childItemProps}
/>
</li>
)
)}
</ul>
</div>
);
}
function MobileNavItem({ items, position: _position, className, ...props }) {
// Need to destructure position from props so that it doesn't get passed on.
const navLinkClassNames = (extraClassName, isSubList = false) =>
clsx(
"menu__link",
{
"menu__link--sublist": isSubList,
},
extraClassName
);
if (!items) {
return (
<li className="menu__list-item">
<NavLink className={navLinkClassNames(className)} {...props} />
</li>
);
}
return (
<li className="menu__list-item">
<NavLink className={navLinkClassNames(className, true)} {...props}>
{props.label}
</NavLink>
<ul className="menu__list">
{items.map(
({ className: childItemClassName, ...childItemProps }, i) => (
<li className="menu__list-item" key={i}>
<NavLink
activeClassName="menu__link--active"
className={navLinkClassNames(childItemClassName)}
{...childItemProps}
onClick={props.onClick}
/>
</li>
)
)}
</ul>
</li>
);
}
// If split links by left/right
// if position is unspecified, fallback to right (as v1)
function splitLinks(links) {
const leftLinks = links.filter(
(linkItem) => (linkItem.position ?? DefaultNavItemPosition) === "left"
);
const rightLinks = links.filter(
(linkItem) => (linkItem.position ?? DefaultNavItemPosition) === "right"
);
return {
leftLinks,
rightLinks,
};
}
function Navbar() {
const {
siteConfig: {
themeConfig: {
navbar: { title, links = [], hideOnScroll = false } = {},
disableDarkMode = false,
},
organizationName,
projectName,
baseUrl,
},
} = useDocusaurusContext();
const [sidebarShown, setSidebarShown] = useState(false);
const [isSearchBarExpanded, setIsSearchBarExpanded] = useState(false);
const { pathname } = useLocation();
const { isDarkTheme, setLightTheme, setDarkTheme } = useThemeContext();
const { navbarRef, isNavbarVisible } = useHideableNavbar(hideOnScroll);
const isMobile = useMedia({ maxWidth: 997 });
const { logoLink, logoLinkProps, logoImageUrl, logoAlt } = useLogo();
useLockBodyScroll(sidebarShown);
@ -70,33 +209,37 @@ function Navbar() {
setSidebarShown(false);
}, [setSidebarShown]);
const onToggleChange = (checked) => {
checked ? setDarkTheme() : setLightTheme();
};
const onToggleChange = useCallback(
(checked) => {
checked ? setDarkTheme() : setLightTheme();
},
[setLightTheme, setDarkTheme]
);
const logoLink = logo.href || baseUrl;
const isExternalLogoLink = /http/.test(logoLink);
const logoLinkProps = isExternalLogoLink
? {
rel: "noopener noreferrer",
target: "_blank",
}
: null;
const logoSrc = logo.srcDark && isDarkTheme ? logo.srcDark : logo.src;
const windowSize = useWindowSize();
const isMobile = useMedia({ maxWidth: 997 });
useEffect(() => {
if (windowSize === windowSizes.desktop) {
setSidebarShown(false);
}
}, [windowSize]);
const { leftLinks, rightLinks } = splitLinks(links);
return (
<nav
ref={navbarRef}
className={classnames("navbar", "navbar--light", "navbar--fixed-top", {
[styles.navbarMain]: pathname === "/",
[styles.navbarOther]: pathname !== "/",
className={clsx("navbar", "navbar--light", "navbar--fixed-top", {
"navbar-sidebar--show": sidebarShown,
[styles.navbarHideable]: hideOnScroll,
[styles.navbarHidden]: !isNavbarVisible,
[styles.navBarBorder]: !isMobile,
})}
>
<div className="navbar__inner">
<div className={classnames("navbar__items", styles.navbarItems)}>
<div className="navbar__items">
{!isMobile && (
<Link
className="navbar__brand"
@ -114,45 +257,40 @@ function Navbar() {
)}
</Link>
)}
<div
aria-label="Navigation bar toggle"
className="navbar__toggle"
role="button"
tabIndex={0}
onClick={showSidebar}
onKeyDown={showSidebar}
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="30"
height="30"
viewBox="0 0 30 30"
role="img"
focusable="false"
{links != null && links.length !== 0 && (
<div
aria-label="Navigation bar toggle"
className="navbar__toggle"
role="button"
tabIndex={0}
onClick={showSidebar}
onKeyDown={showSidebar}
>
<title>Menu</title>
<path
stroke="currentColor"
strokeLinecap="round"
strokeMiterlimit="10"
strokeWidth="2"
d="M4 7h22M4 15h22M4 23h22"
/>
</svg>
</div>
{links
.filter((linkItem) => linkItem.position !== "right")
.map((linkItem, i) => (
<NavLink {...linkItem} key={i} />
))}
</div>
<div
className={classnames(
"navbar__items",
"navbar__items--right",
styles.navbarItemsRight
<svg
xmlns="http://www.w3.org/2000/svg"
width="30"
height="30"
viewBox="0 0 30 30"
role="img"
focusable="false"
>
<title>Menu</title>
<path
stroke="currentColor"
strokeLinecap="round"
strokeMiterlimit="10"
strokeWidth="2"
d="M4 7h22M4 15h22M4 23h22"
/>
</svg>
</div>
)}
>
{leftLinks.map((linkItem, i) => (
<NavItem {...linkItem} key={i} />
))}
</div>
<div className="navbar__items navbar__items--right">
{isMobile && (
<Link
className="navbar__brand"
@ -188,7 +326,7 @@ function Navbar() {
)}
{!isMobile && (
<GithubButton
href={`https://github.com/${siteConfig.organizationName}/${siteConfig.projectName}`}
href={`https://github.com/${organizationName}/${projectName}`}
/>
)}
</div>
@ -202,14 +340,16 @@ function Navbar() {
<div className="navbar-sidebar__brand">
<Link
className="navbar__brand"
to={baseUrl}
aria-label="Home"
title="Home"
onClick={hideSidebar}
to={logoLink}
{...logoLinkProps}
>
<Logo size={32} className={styles.logo} />
{title != null && (
<strong
className={isSearchBarExpanded ? styles.hideLogoText : ""}
className={
isSearchBarExpanded ? styles.hideLogoText : "navbar__title"
}
>
{title}
</strong>
@ -217,7 +357,7 @@ function Navbar() {
</Link>
{sidebarShown && (
<GithubButton
href={`https://github.com/${siteConfig.organizationName}/${siteConfig.projectName}`}
href={`https://github.com/${organizationName}/${projectName}`}
/>
)}
{!disableDarkMode && sidebarShown && (
@ -228,13 +368,7 @@ function Navbar() {
<div className="menu">
<ul className="menu__list">
{links.map((linkItem, i) => (
<li className="menu__list-item" key={i}>
<NavLink
className="menu__link"
{...linkItem}
onClick={hideSidebar}
/>
</li>
<MobileNavItem {...linkItem} onClick={hideSidebar} key={i} />
))}
<div style={{ margin: 5, marginTop: 15 }} />
<SearchBar

View file

@ -1,3 +1,10 @@
/**
* 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.
*/
@media screen and (max-width: 997px) {
.displayOnlyInLargeViewport {
display: none !important;
@ -17,6 +24,7 @@
.navbarHidden {
top: calc(var(--ifm-navbar-height) * -1) !important;
}
.navbarItems {
justify-content: flex-start;
}
@ -29,10 +37,11 @@
position: relative;
margin-left: 2rem;
margin-right: 2rem;
color: var(--ifm-font-color-base);
}
.navLink[class]:hover {
color: var(--ifm-color-white);
color: var(--ifm-color-emphasis-700);
}
html[data-theme="dark"] .navLink[class]:hover {
@ -74,3 +83,7 @@ html[data-theme="dark"] .navbarOther {
.navbarOther {
background-color: var(--ifm-color-white);
}
.navBarBorder {
border-bottom: 1px solid var(--ifm-toc-border-color);
}

View file

@ -0,0 +1,252 @@
/**
* Copyright (c) 2017-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import React, { useCallback, useState } from "react";
import classnames from "classnames";
import Link from "@docusaurus/Link";
import { useLocation } from "react-router-dom";
import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
import useBaseUrl from "@docusaurus/useBaseUrl";
import SearchBar from "@theme/SearchBar";
import useThemeContext from "@theme/hooks/useThemeContext";
import useHideableNavbar from "@theme/hooks/useHideableNavbar";
import useLockBodyScroll from "@theme/hooks/useLockBodyScroll";
import useMedia from "use-media";
import { ColorModeToggle } from "../../components/ColorModeToggle";
import { GithubButton } from "../../components/GithubButton";
import Logo from "../../components/Logo";
import styles from "./styles.module.css";
function NavLink({ to, href, label, position, ...props }) {
const toUrl = useBaseUrl(to);
return (
<Link
className={classnames(styles.navLink, "navbar__item navbar__link")}
{...(href
? {
target: "_blank",
rel: "noopener noreferrer",
href,
}
: {
activeClassName: "navbar__link--active",
to: toUrl,
})}
{...props}
>
{label}
</Link>
);
}
function Navbar() {
const context = useDocusaurusContext();
const { siteConfig = {} } = context;
const { baseUrl, themeConfig = {} } = siteConfig;
const { navbar = {}, disableDarkMode = false } = themeConfig;
const { title, logo = {}, links = [], hideOnScroll = false } = navbar;
const [sidebarShown, setSidebarShown] = useState(false);
const [isSearchBarExpanded, setIsSearchBarExpanded] = useState(false);
const { pathname } = useLocation();
const { isDarkTheme, setLightTheme, setDarkTheme } = useThemeContext();
const { navbarRef, isNavbarVisible } = useHideableNavbar(hideOnScroll);
const isMobile = useMedia({ maxWidth: 997 });
useLockBodyScroll(sidebarShown);
const showSidebar = useCallback(() => {
setSidebarShown(true);
}, [setSidebarShown]);
const hideSidebar = useCallback(() => {
setSidebarShown(false);
}, [setSidebarShown]);
const onToggleChange = (checked) => {
checked ? setDarkTheme() : setLightTheme();
};
const logoLink = logo.href || baseUrl;
const isExternalLogoLink = /http/.test(logoLink);
const logoLinkProps = isExternalLogoLink
? {
rel: "noopener noreferrer",
target: "_blank",
}
: null;
const logoSrc = logo.srcDark && isDarkTheme ? logo.srcDark : logo.src;
return (
<nav
ref={navbarRef}
className={classnames("navbar", "navbar--light", "navbar--fixed-top", {
[styles.navbarMain]: pathname === "/",
[styles.navbarOther]: pathname !== "/",
"navbar-sidebar--show": sidebarShown,
[styles.navbarHideable]: hideOnScroll,
[styles.navbarHidden]: !isNavbarVisible,
})}
>
<div className="navbar__inner">
<div className={classnames("navbar__items", styles.navbarItems)}>
{!isMobile && (
<Link
className="navbar__brand"
to={baseUrl}
aria-label="Home"
title="Home"
>
<Logo size={32} className={styles.logo} />
{title != null && (
<strong
className={isSearchBarExpanded ? styles.hideLogoText : ""}
>
{title}
</strong>
)}
</Link>
)}
<div
aria-label="Navigation bar toggle"
className="navbar__toggle"
role="button"
tabIndex={0}
onClick={showSidebar}
onKeyDown={showSidebar}
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="30"
height="30"
viewBox="0 0 30 30"
role="img"
focusable="false"
>
<title>Menu</title>
<path
stroke="currentColor"
strokeLinecap="round"
strokeMiterlimit="10"
strokeWidth="2"
d="M4 7h22M4 15h22M4 23h22"
/>
</svg>
</div>
{links
.filter((linkItem) => linkItem.position !== "right")
.map((linkItem, i) => (
<NavLink {...linkItem} key={i} />
))}
</div>
<div
className={classnames(
"navbar__items",
"navbar__items--right",
styles.navbarItemsRight
)}
>
{isMobile && (
<Link
className="navbar__brand"
to={baseUrl}
aria-label="Home"
title="Home"
>
<Logo size={32} className={styles.logo} />
{title != null && (
<strong
className={isSearchBarExpanded ? styles.hideLogoText : ""}
>
{title}
</strong>
)}
</Link>
)}
{!isMobile && (
<SearchBar
handleSearchBarToggle={setIsSearchBarExpanded}
isSearchBarExpanded={isSearchBarExpanded}
style={{ marginLeft: "0.5rem", marginRight: "0.5rem" }}
/>
)}
{!disableDarkMode && !isMobile && (
<ColorModeToggle
toggle={onToggleChange}
isDark={isDarkTheme}
style={{ marginLeft: "0.5rem", marginRight: "0.5rem" }}
/>
)}
{!isMobile && (
<GithubButton
href={`https://github.com/${siteConfig.organizationName}/${siteConfig.projectName}`}
/>
)}
</div>
</div>
<div
role="presentation"
className="navbar-sidebar__backdrop"
onClick={hideSidebar}
/>
<div className="navbar-sidebar">
<div className="navbar-sidebar__brand">
<Link
className="navbar__brand"
to={baseUrl}
aria-label="Home"
title="Home"
>
<Logo size={32} className={styles.logo} />
{title != null && (
<strong
className={isSearchBarExpanded ? styles.hideLogoText : ""}
>
{title}
</strong>
)}
</Link>
{sidebarShown && (
<GithubButton
href={`https://github.com/${siteConfig.organizationName}/${siteConfig.projectName}`}
/>
)}
{!disableDarkMode && sidebarShown && (
<ColorModeToggle toggle={onToggleChange} isDark={isDarkTheme} />
)}
</div>
<div className="navbar-sidebar__items">
<div className="menu">
<ul className="menu__list">
{links.map((linkItem, i) => (
<li className="menu__list-item" key={i}>
<NavLink
className="menu__link"
{...linkItem}
onClick={hideSidebar}
/>
</li>
))}
<div style={{ margin: 5, marginTop: 15 }} />
<SearchBar
handleSearchBarToggle={setIsSearchBarExpanded}
isSearchBarExpanded={isSearchBarExpanded}
/>
</ul>
</div>
</div>
</div>
</nav>
);
}
export default Navbar;

View file

@ -0,0 +1,76 @@
@media screen and (max-width: 997px) {
.displayOnlyInLargeViewport {
display: none !important;
}
}
@media (max-width: 360px) {
.hideLogoText {
display: none;
}
}
.navbarHideable {
transition: top 0.2s ease-in-out;
}
.navbarHidden {
top: calc(var(--ifm-navbar-height) * -1) !important;
}
.navbarItems {
justify-content: flex-start;
}
.navbarItemsRight[class] {
flex: 0 0;
}
.navLink[class] {
position: relative;
margin-left: 2rem;
margin-right: 2rem;
}
.navLink[class]:hover {
color: var(--ifm-color-white);
}
html[data-theme="dark"] .navLink[class]:hover {
color: var(--ifm-color-secondary);
}
.navLink[class]:global(.navbar__link--active) {
color: inherit;
font-weight: bold;
}
.navLink[class]:global(.navbar__link--active)::after {
position: absolute;
left: 0;
width: 100%;
height: 1px;
background: var(--ifm-color-content);
content: "";
transition: width 0.5s, opacity 0.5s, transform 0.5s;
transform: translateY(-6px);
}
.toggle {
margin-right: 20px;
}
.navbarMain {
background-color: var(--ifm-background-color);
box-shadow: none;
}
.logo {
margin: 4px;
}
html[data-theme="dark"] .navbarOther {
background-color: var(--ifm-background-color);
}
.navbarOther {
background-color: var(--ifm-color-white);
}

File diff suppressed because it is too large Load diff