mirror of
https://github.com/checktheroads/hyperglass
synced 2024-05-11 05:55:08 +00:00
docs improvements
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
---
|
||||
id: agent
|
||||
title: Linux Agent
|
||||
sidebar_label: Linux Agent
|
||||
id: installation
|
||||
title: Linux Agent Installation
|
||||
sidebar_label: Installation
|
||||
keywords: [configuration, linux, frr, frrouting, bird, agent]
|
||||
description: hyperglass agent configuration
|
||||
---
|
||||
@@ -13,9 +13,9 @@ import TabItem from '@theme/TabItem';
|
||||
Documentation for [hyperglass-agent](https://github.com/checktheroads/hyperglass-agent) is in progress!
|
||||
:::
|
||||
|
||||
# Installation
|
||||
## Installation
|
||||
|
||||
## Dependencies
|
||||
### Dependencies
|
||||
|
||||
On the Linux server running [FRRouting](https://frrouting.org/) or [BIRD](https://bird.network.cz/), make sure Python 3.6+ is installed:
|
||||
|
||||
@@ -51,7 +51,7 @@ $ python3 --version
|
||||
Python 3.6.9
|
||||
```
|
||||
|
||||
## Application
|
||||
### Application
|
||||
|
||||
Now that Python 3.6+ is installed, you can install the hyperglass agent:
|
||||
|
||||
@@ -59,7 +59,7 @@ Now that Python 3.6+ is installed, you can install the hyperglass agent:
|
||||
$ pip3 install --user hyperglass-agent
|
||||
```
|
||||
|
||||
# Setup
|
||||
## Setup
|
||||
|
||||
Just like with hyperglass, the hyperglass agent is easy to set up. To automatically create an application directory, generate SSL certificates, generate and symlink a systemd file, and generate a random secret, run:
|
||||
|
||||
@@ -67,6 +67,24 @@ Just like with hyperglass, the hyperglass agent is easy to set up. To automatica
|
||||
$ hyperglass setup
|
||||
```
|
||||
|
||||
:::note
|
||||
You can also run the setup wizard with certain options disabled, if needed:
|
||||
|
||||
```shell-session
|
||||
$ hyperglass-agent setup --help
|
||||
Usage: hyperglass-agent setup [OPTIONS]
|
||||
|
||||
Run the setup wizard
|
||||
|
||||
Options:
|
||||
--config / --no-config Don't regenerate config file
|
||||
--certs / --no-certs Don't regenerate certificates
|
||||
--systemd / --no-systemd Don't generate a systemd file
|
||||
--force Force regeneration of config file
|
||||
-h, --help Show this message and exit.
|
||||
```
|
||||
:::
|
||||
|
||||
:::important More coming soon
|
||||
Documentation for [hyperglass-agent](https://github.com/checktheroads/hyperglass-agent) is in progress!
|
||||
:::
|
@@ -16,7 +16,7 @@ hyperglass is meant to be _extremely_ customizable, but with reasonable defaults
|
||||
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
|
||||
## Configuration Files
|
||||
|
||||
hyperglass configuration consists of three separate [YAML](https://yaml.org/) configuration files:
|
||||
|
||||
@@ -37,7 +37,7 @@ Configuration files may be located in one of the following directories:
|
||||
- `/etc/hyperglass`
|
||||
- `~/hyperglass`
|
||||
|
||||
# Global Settings
|
||||
## Global Settings
|
||||
|
||||
The following global settings can be set in `hyperglass.yaml`:
|
||||
|
||||
@@ -72,7 +72,7 @@ log_file: /tmp/hyperglass.log
|
||||
cors_origins: [localhost:3000, 192.0.2.1]
|
||||
```
|
||||
|
||||
## Subsections
|
||||
### Subsections
|
||||
|
||||
From the top level, the following subsections may be defined and configured:
|
||||
|
||||
@@ -84,7 +84,7 @@ From the top level, the following subsections may be defined and configured:
|
||||
| `queries` | Enable, disable, or configure query types. | <PageLink to="/docs/queries">➡️</PageLink> |
|
||||
| `web` | Web UI & branding settings. | <PageLink to="/docs/ui">➡️</PageLink> |
|
||||
|
||||
# Adding Devices
|
||||
## Adding Devices
|
||||
|
||||
To add, as an example, a Cisco router, add the following to your `devices.yaml`, with the relevant details changed for your device:
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
---
|
||||
id: devices
|
||||
title: Adding Devices
|
||||
sidebar_label: Device Configuration
|
||||
sidebar_label: Adding Devices
|
||||
keywords: [hyperglass, authentication, ssl, proxy, access list, prefix list, acl, help]
|
||||
description: Adding devices to hyperglass
|
||||
---
|
||||
|
@@ -9,7 +9,7 @@ description: Getting started with hyperglass
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# Automatic installation
|
||||
## Automatic installation
|
||||
|
||||
If your system runs on:
|
||||
|
||||
@@ -27,11 +27,11 @@ $ curl https://raw.githubusercontent.com/checktheroads/hyperglass/v1.0.0/install
|
||||
You should be <i>very</i> 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
|
||||
## Manual Installation
|
||||
|
||||
## System Dependencies
|
||||
### System Dependencies
|
||||
|
||||
### Python
|
||||
#### Python
|
||||
hyperglass is written in Python 3 and requires Python version 3.6 as a minimum dependency.
|
||||
|
||||
If you're confident upgrading your system's version of Python won't break your system (many Linux operating systems rely heavily on Python for package management and other system functions), you can install Python 3.6:
|
||||
@@ -68,7 +68,7 @@ $ python3 --version
|
||||
Python 3.6.9
|
||||
```
|
||||
|
||||
### Other Dependencies
|
||||
#### Other Dependencies
|
||||
The hyperglass UI is written in [ReactJS](https://reactjs.org/). As such, some Javascript dependencies are required. hyperglass also relies on [Redis](https://redis.io/) for caching purposes.
|
||||
|
||||
<Tabs
|
||||
@@ -115,7 +115,7 @@ 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](https://github.com/checktheroads/hyperglass/issues) on Github, and I'll do my best to help out.
|
||||
:::
|
||||
|
||||
## Application
|
||||
### Application
|
||||
|
||||
```bash
|
||||
pip3 install hyperglass
|
||||
|
@@ -5,9 +5,11 @@ sidebar_label: Supported Platforms
|
||||
description: Platforms supported by hyperglass
|
||||
---
|
||||
|
||||
import Link from "@docusaurus/Link";
|
||||
|
||||
## HTTP
|
||||
|
||||
The following platforms use [`hyperglass-agent`](https://github.com/checktheroads/hyperglass-agent) for connection handling. When configuring the `nos` property of a device, use the value in the **Key** column.
|
||||
The following platforms use <Link to="/docs/agent/installation">hyperglass-agent</Link> for connection handling. When configuring the `nos` property of a device, use the value in the **Key** column.
|
||||
|
||||
| Name | Key |
|
||||
| --------- | ------ |
|
||||
|
@@ -1,6 +1,6 @@
|
||||
const githubURL = "https://github.com/checktheroads/hyperglass";
|
||||
|
||||
const { googleTrackingId } = process.env;
|
||||
const { googleTrackingId, algoliaKey } = process.env;
|
||||
|
||||
module.exports = {
|
||||
title: "hyperglass",
|
||||
@@ -16,6 +16,10 @@ module.exports = {
|
||||
trackingID: googleTrackingId || " ",
|
||||
anonymizeIP: false
|
||||
},
|
||||
algolia: {
|
||||
apiKey: algoliaKey,
|
||||
indexName: "BH4D9OD16A"
|
||||
},
|
||||
navbar: {
|
||||
links: [
|
||||
{ to: "docs/introduction", label: "Docs", position: "left" },
|
||||
|
@@ -10,8 +10,8 @@ module.exports = {
|
||||
label: "Configuration",
|
||||
items: ["configuration", "devices", "ui", "cache", "api", "messages", "queries"]
|
||||
},
|
||||
{ type: "category", label: "Linux Agent", items: ["agent/installation"] },
|
||||
{ type: "doc", id: "platforms" },
|
||||
{ type: "doc", id: "agent" },
|
||||
{ type: "doc", id: "license" }
|
||||
]
|
||||
};
|
||||
|
@@ -123,3 +123,23 @@ h5 code,
|
||||
h6 code {
|
||||
color: var(--ifm-color-primary);
|
||||
}
|
||||
|
||||
@media screen and (max-width: 997px) {
|
||||
.col.footer__col[class][class] {
|
||||
text-align: left;
|
||||
}
|
||||
.navbar .navbar__search {
|
||||
padding-left: unset;
|
||||
}
|
||||
.navbar .navbar__search .navbar__search-input {
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.navbar .navbar__search .navbar__search-input {
|
||||
border-radius: var(--ifm-button-border-radius);
|
||||
border-width: var(--ifm-button-border-width);
|
||||
border-color: var(--ifm-navbar-search-input-background-color);
|
||||
border-style: solid;
|
||||
}
|
||||
|
@@ -12,31 +12,49 @@ function Home() {
|
||||
keywords={[
|
||||
"hyperglass",
|
||||
"documentation",
|
||||
"docs",
|
||||
"bgp",
|
||||
"lg",
|
||||
"looking",
|
||||
"glass",
|
||||
"looking glass",
|
||||
"ping",
|
||||
"traceroute",
|
||||
"test"
|
||||
"matt love",
|
||||
"python",
|
||||
"python3",
|
||||
"react",
|
||||
"reactjs"
|
||||
]}
|
||||
>
|
||||
<header className={classnames("hero", styles.heroBanner)}>
|
||||
<div className="container">
|
||||
<h1 className={classnames("hero__title", styles.title)}>hyperglass</h1>
|
||||
<h3 className={classnames("hero__subtitle", styles.subTitle)}>
|
||||
the <span className={styles.tag}>network looking glass</span> that tries to
|
||||
make the internet better.
|
||||
the <span className={styles.tagPrimary}>network looking glass</span> that
|
||||
tries to
|
||||
<span className={styles.tagSecondary}> make the internet better</span>.
|
||||
</h3>
|
||||
<div className={styles.buttons}>
|
||||
<Link
|
||||
className={classnames(
|
||||
"button button--outline button--secondary button--lg",
|
||||
styles.getStarted
|
||||
styles.homeBtn,
|
||||
styles.btnSecondary
|
||||
)}
|
||||
to={useBaseUrl("docs/getting-started")}
|
||||
>
|
||||
Get Started
|
||||
Get a looking glass
|
||||
</Link>
|
||||
<Link
|
||||
className={classnames(
|
||||
"button button--outline button--primary button--lg",
|
||||
styles.homeBtn,
|
||||
styles.btnPrimary
|
||||
)}
|
||||
to={useBaseUrl("docs/introduction")}
|
||||
>
|
||||
Why hyperglass?
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -30,21 +30,32 @@
|
||||
padding: 24px;
|
||||
}
|
||||
|
||||
.getStarted {
|
||||
.homeBtn {
|
||||
color: unset !important;
|
||||
font-size: 24px;
|
||||
padding: 16px 36px;
|
||||
margin: 0.25rem;
|
||||
border-color: unset;
|
||||
}
|
||||
|
||||
.getStarted:hover {
|
||||
.homeBtn:hover {
|
||||
color: unset !important;
|
||||
}
|
||||
|
||||
.btnPrimary:hover {
|
||||
border-color: var(--ifm-color-primary);
|
||||
}
|
||||
|
||||
.btnSecondary:hover {
|
||||
border-color: var(--ifm-color-secondary);
|
||||
}
|
||||
|
||||
.buttons {
|
||||
margin-top: 4vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.content {
|
||||
@@ -57,13 +68,22 @@
|
||||
@media screen and (max-width: 966px) {
|
||||
.heroBanner {
|
||||
padding: 2rem;
|
||||
min-height: 80vh;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2.5rem !important;
|
||||
}
|
||||
|
||||
.homeBtn {
|
||||
min-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.tag {
|
||||
.tagPrimary {
|
||||
color: var(--ifm-color-primary);
|
||||
}
|
||||
|
||||
.tagSecondary {
|
||||
color: var(--ifm-color-secondary);
|
||||
}
|
||||
|
123
docs/src/theme/Footer/index.js
Normal file
123
docs/src/theme/Footer/index.js
Normal file
@@ -0,0 +1,123 @@
|
||||
/**
|
||||
* 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 from "react";
|
||||
import classnames from "classnames";
|
||||
|
||||
import Link from "@docusaurus/Link";
|
||||
import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
|
||||
import useBaseUrl from "@docusaurus/useBaseUrl";
|
||||
import styles from "./styles.module.css";
|
||||
|
||||
function FooterLink({ to, href, label, ...props }) {
|
||||
const toUrl = useBaseUrl(to);
|
||||
return (
|
||||
<Link
|
||||
className="footer__link-item"
|
||||
{...(href
|
||||
? {
|
||||
target: "_blank",
|
||||
rel: "noopener noreferrer",
|
||||
href
|
||||
}
|
||||
: {
|
||||
to: toUrl
|
||||
})}
|
||||
{...props}
|
||||
>
|
||||
{label}
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
|
||||
const FooterLogo = ({ url, alt }) => <img className="footer__logo" alt={alt} src={url} />;
|
||||
|
||||
function Footer() {
|
||||
const context = useDocusaurusContext();
|
||||
const { siteConfig = {} } = context;
|
||||
const { themeConfig = {} } = siteConfig;
|
||||
const { footer } = themeConfig;
|
||||
|
||||
const { copyright, links = [], logo = {} } = footer || {};
|
||||
const logoUrl = useBaseUrl(logo.src);
|
||||
|
||||
if (!footer) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<footer
|
||||
className={classnames("footer", {
|
||||
"footer--dark": footer.style === "dark"
|
||||
})}
|
||||
>
|
||||
<div className="container">
|
||||
{links && links.length > 0 && (
|
||||
<div className="row footer__links">
|
||||
{links.map((linkItem, i) => (
|
||||
<div
|
||||
key={i}
|
||||
className={classnames("col footer__col", styles.footerCol)}
|
||||
>
|
||||
{linkItem.title != null ? (
|
||||
<h4 className="footer__title">{linkItem.title}</h4>
|
||||
) : null}
|
||||
{linkItem.items != null &&
|
||||
Array.isArray(linkItem.items) &&
|
||||
linkItem.items.length > 0 ? (
|
||||
<ul className="footer__items">
|
||||
{linkItem.items.map((item, key) =>
|
||||
item.html ? (
|
||||
<li
|
||||
key={key}
|
||||
className="footer__item"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: item.html
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<li
|
||||
key={item.href || item.to}
|
||||
className="footer__item"
|
||||
>
|
||||
<FooterLink {...item} />
|
||||
</li>
|
||||
)
|
||||
)}
|
||||
</ul>
|
||||
) : null}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
{(logo || copyright) && (
|
||||
<div className="text--center">
|
||||
{logo && logo.src && (
|
||||
<div className="margin-bottom--sm">
|
||||
{logo.href ? (
|
||||
<a
|
||||
href={logo.href}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className={styles.footerLogoLink}
|
||||
>
|
||||
<FooterLogo alt={logo.alt} url={logoUrl} />
|
||||
</a>
|
||||
) : (
|
||||
<FooterLogo alt={logo.alt} url={logoUrl} />
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
{copyright}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
}
|
||||
|
||||
export default Footer;
|
27
docs/src/theme/Footer/styles.module.css
Normal file
27
docs/src/theme/Footer/styles.module.css
Normal file
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
.footerLogoLink {
|
||||
opacity: 0.5;
|
||||
transition: opacity 0.15s ease-in-out;
|
||||
}
|
||||
|
||||
.footerLogoLink:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.footerCol:first-child {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.footerCol:not(:first-child):not(:last-child) {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.footerCol:last-child {
|
||||
text-align: right;
|
||||
}
|
@@ -73,20 +73,6 @@ function Navbar() {
|
||||
setSidebarShown(false);
|
||||
}, [setSidebarShown]);
|
||||
|
||||
// const onToggleChange = useCallback(e => (e.target.checked ? setDarkTheme() : setLightTheme()), [
|
||||
// setLightTheme,
|
||||
// setDarkTheme
|
||||
// ]);
|
||||
|
||||
// const onToggleChange = e => {
|
||||
// console.log(e);
|
||||
// };
|
||||
|
||||
// const onToggleChange = useCallback(e => (e ? setDarkTheme() : setLightTheme()), [
|
||||
// setLightTheme,
|
||||
// setDarkTheme
|
||||
// ]);
|
||||
|
||||
const onToggleChange = checked => {
|
||||
checked ? setDarkTheme() : setLightTheme();
|
||||
};
|
||||
@@ -182,12 +168,12 @@ function Navbar() {
|
||||
checked={isDarkTheme}
|
||||
/>
|
||||
)}
|
||||
{links
|
||||
.filter(linkItem => linkItem.position === "right")
|
||||
.map((linkItem, i) => (
|
||||
<NavLink {...linkItem} key={i} />
|
||||
))}
|
||||
|
||||
{!isMobile && (
|
||||
<SearchBar
|
||||
handleSearchBarToggle={setIsSearchBarExpanded}
|
||||
isSearchBarExpanded={isSearchBarExpanded}
|
||||
/>
|
||||
)}
|
||||
<a
|
||||
className={classnames(
|
||||
styles.displayOnlyInLargeViewport,
|
||||
@@ -199,10 +185,6 @@ function Navbar() {
|
||||
>
|
||||
GITHUB →
|
||||
</a>
|
||||
<SearchBar
|
||||
handleSearchBarToggle={setIsSearchBarExpanded}
|
||||
isSearchBarExpanded={isSearchBarExpanded}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div role="presentation" className="navbar-sidebar__backdrop" onClick={hideSidebar} />
|
||||
@@ -236,8 +218,12 @@ function Navbar() {
|
||||
/>
|
||||
</li>
|
||||
))}
|
||||
|
||||
<div style={{ margin: 5, marginTop: 15 }}></div>
|
||||
<div style={{ margin: 5, marginTop: 15 }} />
|
||||
<SearchBar
|
||||
handleSearchBarToggle={setIsSearchBarExpanded}
|
||||
isSearchBarExpanded={isSearchBarExpanded}
|
||||
/>
|
||||
<div style={{ margin: 5, marginTop: 15 }} />
|
||||
<a
|
||||
className={classnames(
|
||||
"button button--block button--primary",
|
||||
|
533
docs/src/theme/SearchBar/algolia.css
Normal file
533
docs/src/theme/SearchBar/algolia.css
Normal file
File diff suppressed because one or more lines are too long
120
docs/src/theme/SearchBar/index.js
Normal file
120
docs/src/theme/SearchBar/index.js
Normal file
@@ -0,0 +1,120 @@
|
||||
/**
|
||||
* 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, {useState, useRef, useCallback} from 'react';
|
||||
import classnames from 'classnames';
|
||||
|
||||
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
||||
import {useHistory} from '@docusaurus/router';
|
||||
|
||||
import './styles.css';
|
||||
|
||||
const Search = props => {
|
||||
const [algoliaLoaded, setAlgoliaLoaded] = useState(false);
|
||||
const searchBarRef = useRef(null);
|
||||
const {siteConfig = {}} = useDocusaurusContext();
|
||||
const {
|
||||
themeConfig: {algolia},
|
||||
} = siteConfig;
|
||||
const history = useHistory();
|
||||
|
||||
function initAlgolia(focus) {
|
||||
window.docsearch({
|
||||
appId: algolia.appId,
|
||||
apiKey: algolia.apiKey,
|
||||
indexName: algolia.indexName,
|
||||
inputSelector: '#search_input_react',
|
||||
algoliaOptions: algolia.algoliaOptions,
|
||||
// Override algolia's default selection event, allowing us to do client-side
|
||||
// navigation and avoiding a full page refresh.
|
||||
handleSelected: (_input, _event, suggestion) => {
|
||||
// Use an anchor tag to parse the absolute url into a relative url
|
||||
// Alternatively, we can use new URL(suggestion.url) but its not supported in IE
|
||||
const a = document.createElement('a');
|
||||
a.href = suggestion.url;
|
||||
|
||||
// Algolia use closest parent element id #__docusaurus when a h1 page title does not have an id
|
||||
// So, we can safely remove it. See https://github.com/facebook/docusaurus/issues/1828 for more details.
|
||||
const routePath =
|
||||
`#__docusaurus` === a.hash
|
||||
? `${a.pathname}`
|
||||
: `${a.pathname}${a.hash}`;
|
||||
history.push(routePath);
|
||||
},
|
||||
});
|
||||
|
||||
if (focus) {
|
||||
searchBarRef.current.focus();
|
||||
}
|
||||
}
|
||||
|
||||
const loadAlgolia = (focus = true) => {
|
||||
if (algoliaLoaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
Promise.all([import('docsearch.js'), import('./algolia.css')]).then(
|
||||
([{default: docsearch}]) => {
|
||||
setAlgoliaLoaded(true);
|
||||
window.docsearch = docsearch;
|
||||
initAlgolia(focus);
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
const handleSearchIcon = useCallback(() => {
|
||||
loadAlgolia();
|
||||
|
||||
if (algoliaLoaded) {
|
||||
searchBarRef.current.focus();
|
||||
}
|
||||
|
||||
props.handleSearchBarToggle(!props.isSearchBarExpanded);
|
||||
}, [props.isSearchBarExpanded]);
|
||||
|
||||
const handleSearchInputBlur = useCallback(() => {
|
||||
props.handleSearchBarToggle(!props.isSearchBarExpanded);
|
||||
}, [props.isSearchBarExpanded]);
|
||||
|
||||
const handleSearchInput = useCallback(e => {
|
||||
const needFocus = e.type !== 'mouseover';
|
||||
|
||||
loadAlgolia(needFocus);
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="navbar__search" key="search-box">
|
||||
<span
|
||||
aria-label="expand searchbar"
|
||||
role="button"
|
||||
className={classnames('search-icon', {
|
||||
'search-icon-hidden': props.isSearchBarExpanded,
|
||||
})}
|
||||
onClick={handleSearchIcon}
|
||||
onKeyDown={handleSearchIcon}
|
||||
tabIndex={0}
|
||||
/>
|
||||
<input
|
||||
id="search_input_react"
|
||||
type="search"
|
||||
placeholder="Search"
|
||||
aria-label="Search"
|
||||
className={classnames(
|
||||
'navbar__search-input',
|
||||
{'search-bar-expanded': props.isSearchBarExpanded},
|
||||
{'search-bar': !props.isSearchBarExpanded},
|
||||
)}
|
||||
onMouseOver={handleSearchInput}
|
||||
onFocus={handleSearchInput}
|
||||
onBlur={handleSearchInputBlur}
|
||||
ref={searchBarRef}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Search;
|
40
docs/src/theme/SearchBar/styles.css
Normal file
40
docs/src/theme/SearchBar/styles.css
Normal file
@@ -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.
|
||||
*/
|
||||
|
||||
.search-icon {
|
||||
background-image: var(--ifm-navbar-search-input-icon);
|
||||
height: auto;
|
||||
width: 24px;
|
||||
cursor: pointer;
|
||||
padding: 8px;
|
||||
line-height: 32px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.search-icon-hidden {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
@media (max-width: 360px) {
|
||||
.search-bar {
|
||||
width: 0 !important;
|
||||
background: none !important;
|
||||
padding: 0 !important;
|
||||
transition: none !important;
|
||||
}
|
||||
|
||||
.search-bar-expanded {
|
||||
width: 9rem !important;
|
||||
}
|
||||
|
||||
.search-icon {
|
||||
display: inline;
|
||||
vertical-align: sub;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user