From a3cd810746b79321cecdf7fc13527eb0a12d3c0d Mon Sep 17 00:00:00 2001 From: checktheroads Date: Fri, 28 Feb 2020 01:26:12 -0700 Subject: [PATCH] docs updates --- docs/docs/api.mdx | 10 +- docs/docs/cache.mdx | 10 +- docs/docs/configuration.mdx | 21 +- docs/docs/devices.mdx | 7 +- docs/docs/getting-started.mdx | 38 +- docs/docs/introduction.mdx | 6 +- docs/docs/setup.mdx | 66 ++ docs/docs/ui.mdx | 72 +- docs/docusaurus.config.js | 10 +- docs/package.json | 7 +- docs/src/css/custom.css | 36 + docs/src/pages/index.js | 104 +-- docs/src/pages/styles.module.css | 83 +- docs/src/theme/CodeBlock/index.js | 111 +++ docs/src/theme/CodeBlock/styles.module.css | 40 + docs/src/theme/Navbar/index.js | 50 +- docs/src/theme/Navbar/styles.module.css | 10 +- docs/yarn.lock | 970 +++++++++++---------- 18 files changed, 926 insertions(+), 725 deletions(-) mode change 100755 => 100644 docs/src/pages/index.js mode change 100755 => 100644 docs/src/pages/styles.module.css create mode 100755 docs/src/theme/CodeBlock/index.js create mode 100755 docs/src/theme/CodeBlock/styles.module.css diff --git a/docs/docs/api.mdx b/docs/docs/api.mdx index eb0d322..fdb9da3 100644 --- a/docs/docs/api.mdx +++ b/docs/docs/api.mdx @@ -7,7 +7,6 @@ description: hyperglass API configuration --- import Link from "@docusaurus/Link"; -import Admonition from "react-admonitions"; import MiniNote from "../src/components/MiniNote"; import Code from "../src/components/JSXCode"; import PageLink from "../src/components/PageLink"; @@ -81,9 +80,6 @@ docs: uri: /api/docs ``` - - I'm partial to Redoc, partially because I find it to be more aesthetically pleasing, and - partially because it's written in ReactJS, just like the - hyperglass UI. At some point, I plan to migrate away from the built-in Redoc page and integrate - Redoc directly with hyperglass. - +:::note From the developer +I'm partial to Redoc, partially because I find it to be more aesthetically pleasing, and partially because it's written in [ReactJS](https://reactjs.org/), just like the hyperglass UI. At some point, I plan to migrate away from the built-in Redoc page and integrate Redoc directly with hyperglass. +::: diff --git a/docs/docs/cache.mdx b/docs/docs/cache.mdx index 5dd6a97..39a2a59 100644 --- a/docs/docs/cache.mdx +++ b/docs/docs/cache.mdx @@ -7,7 +7,6 @@ description: hyperglass caching configuration --- import Link from "@docusaurus/Link"; -import Admonition from "react-admonitions"; hyperglass uses [Redis](https://redis.io/) for cache storage. Every query is cached and automatically expired from the cache after a configurable timeout period. @@ -21,12 +20,9 @@ Common Redis parameters are configurable, in case you already have a dedicated R | `timeout` | Integer | `120` | Time in seconds query output will be kept in the Redis cache. | | `show_text` | Boolean | `true` | Show the cache message in the hyperglass UI. | - - hyperglass caches every query response to a Redis database, and always responds to a request - with the cached value. If hyperglass receives a query for which it has no matching cached entry, - the query parameters are used to created a new cache entry, hyperglass executes the request - normally, writes the response to the cache, and then returns the response to the end user. - +:::important Caching +hyperglass caches every query response to a Redis database, and always responds to a request with the cached value. If hyperglass receives a query for which it has no matching cached entry, the query parameters are used to created a new cache entry, hyperglass executes the request normally, writes the response to the cache, and then returns the response to the end user. +::: ## Example diff --git a/docs/docs/configuration.mdx b/docs/docs/configuration.mdx index 6bd111f..29df27f 100644 --- a/docs/docs/configuration.mdx +++ b/docs/docs/configuration.mdx @@ -7,17 +7,14 @@ description: Configuring hyperglass --- import Link from "@docusaurus/Link"; -import Admonition from "react-admonitions"; import MiniNote from "../src/components/MiniNote"; import PageLink from "../src/components/PageLink"; hyperglass is meant to be _extremely_ customizable, but with reasonable defaults that most operators won't need to override. Even though there are a _lot_ of configuration options, all of them can be left untouched and hyperglass will work (although, it's recommended to at least set the organization name). - - On the back end, hyperglass uses strict configuration schema validation, so it's virtually - impossible to configure hyperglass incorrectly without receiving a contextual warning about - what's missing or incorrect about a configuration. - +:::tip Validation +On the back end, hyperglass uses strict configuration schema validation, so it's virtually impossible to configure hyperglass incorrectly without receiving a contextual warning about what's missing or incorrect about a configuration. +::: # Configuration Files @@ -113,12 +110,6 @@ routers: There are a lot more options, but this is enough to get started. For all device configuration options, see here. - - If you have a lot of devices with shared configuration parameters, you may want to look into{" "} - YAML Anchors and Aliases. If you've never used them before, they can be pretty - weird looking at first read. Atlassian{" "} - - has a pretty decent guide - - . - +:::tip YAML +If you have a lot of devices with shared configuration parameters, you may want to look into **YAML Anchors and Aliases**. If you've never used them before, they can be pretty weird looking at first read. Atlassian [has a pretty decent guide](https://confluence.atlassian.com/bitbucket/yaml-anchors-960154027.html). +::: diff --git a/docs/docs/devices.mdx b/docs/docs/devices.mdx index fb6ecce..46452c7 100644 --- a/docs/docs/devices.mdx +++ b/docs/docs/devices.mdx @@ -7,7 +7,6 @@ description: Adding devices to hyperglass --- import Link from "@docusaurus/Link"; -import Admonition from "react-admonitions"; import R from "../src/components/Required"; import MiniNote from "../src/components/MiniNote"; import Code from "../src/components/JSXCode"; @@ -39,9 +38,9 @@ Any device that uses SSH (see platforms for br | `nos` | String | `'linux_ssh'` | Proxy's network operating system. Must be a supported platform. | | `port` | Integer | `22` | TCP port user to connect to the proxy. | - - Currently only linux_ssh has been tested and validated for use as an SSH proxy. - +:::important +Currently, only `linux_ssh` has been tested and validated for use as an SSH proxy. +::: ### `credential` diff --git a/docs/docs/getting-started.mdx b/docs/docs/getting-started.mdx index 8dfb14b..11e6363 100755 --- a/docs/docs/getting-started.mdx +++ b/docs/docs/getting-started.mdx @@ -7,11 +7,7 @@ description: Getting started with hyperglass --- import Tabs from '@theme/Tabs'; -import Link from "@docusaurus/Link"; import TabItem from '@theme/TabItem'; -import Admonition from "react-admonitions"; -import Code from "../src/components/JSXCode"; - # Automatic installation @@ -23,13 +19,13 @@ If your system runs on: You should be able to proceed with the automatic installation: -```bash -curl https://raw.githubusercontent.com/checktheroads/hyperglass/v1.0.0/install.sh | sudo bash +```shell-session +$ curl https://raw.githubusercontent.com/checktheroads/hyperglass/v1.0.0/install.sh | sudo bash ``` - - You should be very worried when someone asks you to do what I just did. Downloading a bash script from the internet and piping it to bash with root privileges is a terrible idea, unless you fully trust the source. Please don't trust me - go look at the code and determine for your self if it's safe to execute. If you feel it's not, please proceed with the manual installation. - +:::caution Piping to bash +You should be very worried when someone asks you to do what I just did. Downloading a bash script from the internet and piping it to `bash` with root privileges is a terrible idea, unless you fully trust the source. Please don't trust me - go [look at the code](https://github.com/checktheroads/hyperglass/blob/v1.0.0/install.sh) and determine for your self if it's safe to execute. If you feel it's not, please proceed with the manual installation (and [tell me why](https://github.com/checktheroads/hyperglass/issues), so I can fix it). +::: # Manual Installation @@ -48,17 +44,17 @@ If you're confident upgrading your system's version of Python won't break your s -```bash -sudo apt install -y python3.6-dev python3-pip +```shell-session +$ sudo apt install -y python3.6-dev python3-pip ``` -```bash -sudo yum install centos-release-scl -sudo yum install rh-python36 +```shell-session +$ sudo yum install centos-release-scl +$ sudo yum install rh-python36 ``` @@ -67,9 +63,9 @@ sudo yum install rh-python36 You can then verify your Python 3 version: -```bash -python3 --version -# Python 3.6.9 +```shell-session +$ python3 --version +Python 3.6.9 ``` ### Other Dependencies @@ -115,14 +111,12 @@ sudo yum -y install gcc-c++ make nodejs yarn redis - -I've attempted to abstract away most of the Javascript-related configuration and operational steps, because I think I might be the only network engineer on the planet who actually doesn't mind JS 😂. If you run into any issues with the NodeJS/Yarn installation processes, don't hesitate to raise an issue on Github, and I'll do my best to help out. - +:::note From the Developer +I've attempted to abstract away most of the Javascript-related configuration and operational steps, because I think I might be the only network engineer on the planet who actually doesn't mind JS 😂. If you run into any issues with the NodeJS/Yarn installation processes, don't hesitate to [raise an issue](https://github.com/checktheroads/hyperglass/issues) on Github, and I'll do my best to help out. +::: ## Application ```bash pip3 install hyperglass ``` - - diff --git a/docs/docs/introduction.mdx b/docs/docs/introduction.mdx index 1477347..7982627 100644 --- a/docs/docs/introduction.mdx +++ b/docs/docs/introduction.mdx @@ -9,13 +9,13 @@ import useBaseUrl from "@docusaurus/useBaseUrl"; import classnames from "classnames"; import styles from "./styles.module.css"; -# What is hyperglass? +## What is hyperglass? **hyperglass** is an open source network looking glass written by a network engineer for other network engineers. The purpose of a looking glass is to provide customers, peers, and complete strangers with unattended visibility into the an operator's network. hyperglass was created with the lofty goal of benefiting the internet community at-large by providing a faster, easier, and more secure way for operators to provide looking glass services to their customers, peers, and other network operators. -# Features +## Features - BGP Route, BGP Community, BGP AS Path, Ping, & Traceroute - Full IPv6 support @@ -42,4 +42,4 @@ hyperglass was created with the lofty goal of benefiting the internet community className={classnames('button button--outline button--secondary button--lg', styles.getStarted,)} to={useBaseUrl('docs/getting-started')}> Get Started - \ No newline at end of file + diff --git a/docs/docs/setup.mdx b/docs/docs/setup.mdx index fe69aff..c590f1e 100644 --- a/docs/docs/setup.mdx +++ b/docs/docs/setup.mdx @@ -5,3 +5,69 @@ sidebar_label: Setup keywords: [install, setup] description: hyperglass Setup --- + +import Link from "@docusaurus/Link"; + +After hyperglass is installed, you can run the `hyperglass --help` command to see the available options: + +```shell-session +$ hyperglass --help +Usage: hyperglass [OPTIONS] COMMAND [ARGS]... + + hyperglass Command Line Interface + +Options: + -v, --version 🔢 hyperglass version + -h, --help 🙏 Show this help message + +Commands: + build-ui 🦋 Create a new UI build + secret 🔒 Generate agent secret + setup 🧰 Run the setup wizard + start 🚀 Start web server +``` + +## Setup Wizard + +To start the setup wizard, run `hyperglass setup` and you'll receive the following prompts: + +### Installation Directory + +```shell-session +[?] Choose a directory for hyperglass: /Users/ml/hyperglass + > /home/user/hyperglass + /etc/hyperglass +``` + +hyperglass requires a directory on your system to store configuration files, the web UI, logos, etc. You may choose between the current user's home directory or `/etc`. + +### Configuration files + +```shell-session +Do you want to install example configuration files? (This is non-destructive) [y/N]: +``` + +hyperglass can install example configuration files to your hyperglass installation directory to make it a little easier to get up and running. + +### Systemd Service + +```shell-session +Do you want to generate a systemd service file? [y/N]: +``` + +hyperglass also includes a [systemd](https://systemd.io/) service file, which can be installed if you use systemd. If selected, a systemd service file will be generated and copied to the installation directory. Then, it will be symlinked to `/etc/systemd/system`. All you need to do to enable the service is run: + +```shell-session +$ sudo systemctl enable hyperglass +``` + +## UI Build + +hyperglass is build with [NextJS](https://nextjs.org/), a [React](https://reactjs.org/)-based UI framework that supports server-side rendering and static exporting, which contribute to hyperglass's speed and SEO-friendliness. At startup, hyperglass creates a new "UI build", which is a static export of the site and includes some elements of the configuration. + +It is recommended to run an initial UI build after running the setup wizard, so that you can verify that the installation is working prior to diving into configuration. + +```shell-session +$ hyperglass build-ui +✅ Completed UI build in production mode +``` diff --git a/docs/docs/ui.mdx b/docs/docs/ui.mdx index df2470a..97f065d 100644 --- a/docs/docs/ui.mdx +++ b/docs/docs/ui.mdx @@ -7,7 +7,6 @@ description: hyperglass Web UI Configuration --- import Link from "@docusaurus/Link"; -import Admonition from "react-admonitions"; import R from "../src/components/Required"; import MiniNote from "../src/components/MiniNote"; import Code from "../src/components/JSXCode"; @@ -60,7 +59,7 @@ web: title: Terms text: cache: Results will be cached for 2 minutes. - fqdn_tooltip: 'Use {protocol}' + fqdn_tooltip: "Use {protocol}" query_location: Location query_target: Target query_type: Query Type @@ -99,13 +98,9 @@ web: | :-------- | :-----: | :-----: | :--------------------------------------------------------------------------------------- | | `enable` | Boolean | `true` | Enable or disable the display of developer credit & link to hyperglass GitHub repository | - - If your organization's policy allows, and you don't mind, I request that you keep{" "} - credit enabled. Remember: my goal for this project is get more networks to use - looking glasses to make all of our lives easier.
-
Because it's primarily other network operators that will use this tool to begin with, I'd - love for any operators that use your looking glass to know where they can get their own. -
+:::note From the developer +If your organization's policy allows, and you don't mind, I request that you keep `credit` enabled. Remember: my goal for this project is get more networks to use looking glasses to make all of our lives easier. Because it's primarily other network operators who will use this tool to begin with, I'd love for any operators that use your looking glass to know where they can get their own. +::: ## `dns_provider` @@ -164,52 +159,17 @@ By default, no Opengraph image is set. If you define one with `image`, hyperglas | `title` | String | `'hyperglass'` | Title text. | | `title_mode` | String | `'text_only'` | Set the title mode. Must be text_only, logo_only, logo_title, or all | - - The title_mode parameter behaves in the following manner: -
- - - - - - - - - - - - - - - - - - - - - - - - - -
ModeBehavior
- text_only - - Shows the title and subtitle only. -
- logo_only - - Shows the logo only. -
- logo_title - - Shows the logo and title only. -
- all - - Shows the logo, title, and subtitle. -
-
+:::important Title Mode +The `title_mode` parameter behaves in the following manner: + +| Mode | Behavior | +| ------------ | ------------------------------------------------------------------ | +| `text_only` | Shows the `title` and `subtitle` only. | +| `logo_only` | Shows the `logo` only. | +| `logo_title` | Shows the `logo` and `title` only. | +| `all` | Shows the `logo`, `title`, and `subtitle`. | + +::: ## `theme` @@ -249,5 +209,3 @@ Currently, only [Google Fonts](https://fonts.google.com/) are supported. | :-------- | :----: | :----------------------- | :-------------------------------------- | | `body` | String | | Main body font | | `mono` | String | | Monospace font, used for command output | - - diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index 2bfc391..6a32b31 100755 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -10,11 +10,11 @@ module.exports = { projectName: "hyperglass", themeConfig: { navbar: { - title: "hyperglass", - logo: { - alt: "hyperglass icon", - src: "img/icon.svg" - }, + // title: "hyperglass", + // logo: { + // alt: "hyperglass icon", + // src: "img/icon.svg" + // }, links: [ { to: "docs/introduction", label: "Docs", position: "left" }, { to: "screenshots", label: "Screenshots", position: "left" }, diff --git a/docs/package.json b/docs/package.json index e42e473..338eeac 100755 --- a/docs/package.json +++ b/docs/package.json @@ -9,11 +9,12 @@ "deploy": "docusaurus deploy" }, "dependencies": { - "@docusaurus/core": "^2.0.0-alpha.40", - "@docusaurus/preset-classic": "^2.0.0-alpha.40", + "@docusaurus/core": "^2.0.0-alpha.43", + "@docusaurus/preset-classic": "^2.0.0-alpha.43", "classnames": "^2.2.6", + "prismjs": "^1.19.0", + "prop-types": "^15.7.2", "react": "^16.8.4", - "react-admonitions": "^2.1.0", "react-dom": "^16.8.4" }, "browserslist": { diff --git a/docs/src/css/custom.css b/docs/src/css/custom.css index f9037c3..43fef73 100755 --- a/docs/src/css/custom.css +++ b/docs/src/css/custom.css @@ -5,6 +5,9 @@ */ /* You can override the default Infima variables here. */ +@import url("https://fonts.googleapis.com/css?family=Nunito:200,400,700&display=swap"); +@import url("https://fonts.googleapis.com/css?family=Fira+Code&display=swap"); + :root { --ifm-font-size-sm: 12px; /* --ifm-color-secondary: #314cb6; @@ -29,6 +32,12 @@ --ifm-color-primary-lighter: #ff918f; --ifm-color-primary-lightest: #ffc4c3; --ifm-code-font-size: 95%; + --ifm-navbar-background-color: var(--ifm-background-color); + --ifm-font-family-base: "Nunito", system-ui, -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell, + Noto Sans, sans-serif, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, + "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + --ifm-font-family-monospace: "Fira Code", SFMono-Regular, Menlo, Monaco, Consolas, + "Liberation Mono", "Courier New", monospace; } :root { @@ -40,6 +49,23 @@ --ifm-footer-background-color: var(--ifm-color-emphasis-100); } +:root { + --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); +} + +html[data-theme="dark"]:root { + --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); +} + html[data-theme="dark"] .footer.footer--dark { --ifm-footer-color: var(--ifm-color-emphasis-300); } @@ -64,6 +90,16 @@ html[data-theme="dark"] { */ } +.admonition { + --ifm-code-background: rgba(255, 255, 255, 0.5); + --ifm-code-color: var(--ifm-color-secondary-darker); + --ifm-link-color: rgba(0, 0, 0, 0.5); +} + +.admonition a:hover { + color: rgba(0, 0, 0, 0.5); +} + .docusaurus-highlight-code-line { background-color: rgb(72, 77, 91); display: block; diff --git a/docs/src/pages/index.js b/docs/src/pages/index.js old mode 100755 new mode 100644 index fe08cb8..7f7da63 --- a/docs/src/pages/index.js +++ b/docs/src/pages/index.js @@ -2,77 +2,39 @@ import React from "react"; import classnames from "classnames"; import Layout from "@theme/Layout"; import Link from "@docusaurus/Link"; -import useDocusaurusContext from "@docusaurus/useDocusaurusContext"; import useBaseUrl from "@docusaurus/useBaseUrl"; import styles from "./styles.module.css"; -const features = [ - { - title: <>Easy to Use, - imageUrl: "img/undraw_docusaurus_mountain.svg", - description: ( - <> - Docusaurus was designed from the ground up to be easily installed and used to get - your website up and running quickly. - - ) - }, - { - title: <>Focus on What Matters, - imageUrl: "img/undraw_docusaurus_tree.svg", - description: ( - <> - Docusaurus lets you focus on your docs, and we'll do the chores. Go ahead and - move your docs into the docs directory. - - ) - }, - { - title: <>Powered by React, - imageUrl: "img/undraw_docusaurus_react.svg", - description: ( - <> - Extend or customize your website layout by reusing React. Docusaurus can be extended - while reusing the same header and footer. - - ) - } -]; - -function Feature({ imageUrl, title, description }) { - const imgUrl = useBaseUrl(imageUrl); - return ( -
- {imgUrl && ( -
- {title} -
- )} -

{title}

-

{description}

-
- ); -} - function Home() { - const context = useDocusaurusContext(); - const { siteConfig = {} } = context; return ( -
+
-

{siteConfig.title}

-

{siteConfig.tagline}

+

hyperglass

+

+ the network looking glass that tries to + make the internet better. +

Get Started @@ -80,20 +42,22 @@ function Home() {
- {features && features.length && ( -
-
-

- This site is currently under construction -

-
- {features.map((props, idx) => ( - - ))} +
+
+
+
+
+
+
+
+
+
+
+
-
- )} +
+
); diff --git a/docs/src/pages/styles.module.css b/docs/src/pages/styles.module.css old mode 100755 new mode 100644 index 4d6f613..984a396 --- a/docs/src/pages/styles.module.css +++ b/docs/src/pages/styles.module.css @@ -1,46 +1,69 @@ +/** + * 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. + */ + /** * CSS files with the .module.css suffix will be treated as CSS modules * and scoped locally. */ - -.heroBanner[class] { - padding: 4rem 0; +.heroBanner { + /* background-color: var(--neutron-color-dark); */ + background-color: var(--ifm-background-color); + color: var(--neutron-color-lighter); + padding: 128px; text-align: center; position: relative; overflow: hidden; } +.title[class] { + font-weight: 200; + font-size: 4rem; +} + +.subTitle[class] { + font-weight: 200; + font-size: 2rem; + padding: 24px; +} + +.getStarted { + color: unset !important; + font-size: 24px; + padding: 16px 36px; +} + +.getStarted:hover { + color: unset !important; +} + +.buttons { + margin-top: 4vh; + display: flex; + align-items: center; + justify-content: center; +} + +.content { + align-items: center; + display: flex; + padding: 36px 0; + width: 100%; +} + @media screen and (max-width: 966px) { .heroBanner { padding: 2rem; } + + .title { + font-size: 2.5rem !important; + } } -.buttons { - display: flex; - align-items: center; - justify-content: center; -} - -.features { - display: flex; - align-items: center; - padding: 2rem 0; - width: 100%; -} - -.featureImage { - height: 200px; - width: 200px; -} - -.getStarted[class][class]:not(.button--active):not(:hover) { - color: white; - border-color: white; -} - -.getStarted[class]:hover { - background-color: var(--ifm-color-secondary); - color: white; - border-color: none; +.tag { + color: var(--ifm-color-primary); } diff --git a/docs/src/theme/CodeBlock/index.js b/docs/src/theme/CodeBlock/index.js new file mode 100755 index 0000000..33c74a9 --- /dev/null +++ b/docs/src/theme/CodeBlock/index.js @@ -0,0 +1,111 @@ +/** + * 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, { 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 "prism-react-renderer/themes/dracula"; +import Clipboard from "clipboard"; +import rangeParser from "parse-numeric-range"; +import useDocusaurusContext from "@docusaurus/useDocusaurusContext"; +import styles from "./styles.module.css"; + +const highlightLinesRangeRegex = /{([\d,-]+)}/; + +export default ({ children, className: languageClassName, metastring }) => { + (typeof global !== "undefined" ? global : window).Prism = Prism; + require("prismjs/components/prism-shell-session"); + require("prismjs/components/prism-yaml"); + const { + siteConfig: { + themeConfig: { prism = {} } + } + } = useDocusaurusContext(); + const [showCopied, setShowCopied] = useState(false); + const target = useRef(null); + const button = useRef(null); + let highlightLines = []; + + if (metastring && highlightLinesRangeRegex.test(metastring)) { + const highlightLinesRange = metastring.match(highlightLinesRangeRegex)[1]; + highlightLines = rangeParser.parse(highlightLinesRange).filter(n => n > 0); + } + + useEffect(() => { + let clipboard; + + if (button.current) { + clipboard = new Clipboard(button.current, { + target: () => target.current + }); + } + + return () => { + if (clipboard) { + clipboard.destroy(); + } + }; + }, [button.current, target.current]); + + let language = languageClassName && languageClassName.replace(/language-/, ""); + + if (!language && prism.defaultLanguage) { + language = prism.defaultLanguage; + } + + const handleCopyCode = () => { + window.getSelection().empty(); + setShowCopied(true); + + setTimeout(() => setShowCopied(false), 2000); + }; + + return ( + + {({ className, style, tokens, getLineProps, getTokenProps }) => ( +
+
+                        {tokens.map((line, i) => {
+                            const lineProps = getLineProps({ line, key: i });
+
+                            if (highlightLines.includes(i + 1)) {
+                                lineProps.className = `${lineProps.className} docusaurus-highlight-code-line`;
+                            }
+
+                            return (
+                                
+ {line.map((token, key) => ( + + ))} +
+ ); + })} +
+ {/* */} +
+ )} +
+ ); +}; diff --git a/docs/src/theme/CodeBlock/styles.module.css b/docs/src/theme/CodeBlock/styles.module.css new file mode 100755 index 0000000..83c9e16 --- /dev/null +++ b/docs/src/theme/CodeBlock/styles.module.css @@ -0,0 +1,40 @@ +/** + * 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. + */ + +.codeBlock { + margin-bottom: 0; + overflow: hidden; + overflow-wrap: break-word; + white-space: pre-wrap; +} + +.codeBlockWrapper { + position: relative; +} + +.codeBlockWrapper:hover > .copyButton { + visibility: visible; + opacity: 1; +} + +.copyButton { + background: rgb(1, 22, 39); + border: 1px solid rgb(214, 222, 235); + border-radius: var(--ifm-global-radius); + color: rgb(214, 222, 235); + cursor: pointer; + line-height: 12px; + opacity: 0; + outline: none; + padding: 4px 8px; + position: absolute; + right: var(--ifm-pre-padding); + top: var(--ifm-pre-padding); + visibility: hidden; + transition: opacity 200ms ease-in-out, visibility 200ms ease-in-out, + bottom 200ms ease-in-out; +} diff --git a/docs/src/theme/Navbar/index.js b/docs/src/theme/Navbar/index.js index 5b6aa8e..a3bce1e 100644 --- a/docs/src/theme/Navbar/index.js +++ b/docs/src/theme/Navbar/index.js @@ -16,8 +16,9 @@ import Toggle from "@theme/Toggle"; import classnames from "classnames"; -import useTheme from "@theme/hooks/useTheme"; +import useThemeContext from "@theme/hooks/useThemeContext"; import useHideableNavbar from "@theme/hooks/useHideableNavbar"; +import useLockBodyScroll from "@theme/hooks/useLockBodyScroll"; import Logo from "../../components/Logo"; import styles from "./styles.module.css"; @@ -50,26 +51,39 @@ function Navbar() { 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 [theme, setTheme] = useTheme(); const { pathname } = useLocation(); + const { isDarkTheme, setLightTheme, setDarkTheme } = useThemeContext(); const { navbarRef, isNavbarVisible } = useHideableNavbar(hideOnScroll); + useLockBodyScroll(sidebarShown); + const showSidebar = useCallback(() => { - document.body.style.overflow = "hidden"; setSidebarShown(true); }, [setSidebarShown]); const hideSidebar = useCallback(() => { - document.body.style.overflow = "visible"; setSidebarShown(false); }, [setSidebarShown]); - const onToggleChange = useCallback(e => setTheme(e.target.checked ? "dark" : ""), [setTheme]); + const onToggleChange = useCallback(e => (e.target.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 logoImageUrl = useBaseUrl(logoSrc); - const logoUrl = useBaseUrl(logo.src); - const logoDark = useBaseUrl(logo.dark); return (