mirror of
https://github.com/facebook/docusaurus.git
synced 2025-06-06 21:03:47 +02:00
feat(v2): add announcement bar (#2330)
* feat(v2): add announcement bar * Refactor: move to Layout * Fixes * Refactor to simplify * Changes: id, styles, docs
This commit is contained in:
parent
c3aa162ea5
commit
0f73a1fad8
7 changed files with 152 additions and 4 deletions
|
@ -0,0 +1,70 @@
|
||||||
|
/**
|
||||||
|
* 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, {useState, useEffect} from 'react';
|
||||||
|
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
||||||
|
|
||||||
|
import styles from './styles.module.css';
|
||||||
|
|
||||||
|
const STORAGE_DISMISS_KEY = 'docusaurus.announcement.dismiss';
|
||||||
|
const STORAGE_ID_KEY = 'docusaurus.announcement.id';
|
||||||
|
|
||||||
|
function AnnouncementBar() {
|
||||||
|
const {
|
||||||
|
siteConfig: {themeConfig: {announcementBar = {}}} = {},
|
||||||
|
} = useDocusaurusContext();
|
||||||
|
const {id, content, backgroundColor, textColor} = announcementBar;
|
||||||
|
const [isClosed, setClosed] = useState(true);
|
||||||
|
const handleClose = () => {
|
||||||
|
sessionStorage.setItem(STORAGE_DISMISS_KEY, true);
|
||||||
|
setClosed(true);
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const viewedId = sessionStorage.getItem(STORAGE_ID_KEY);
|
||||||
|
const isNewAnnouncement = id !== viewedId;
|
||||||
|
|
||||||
|
sessionStorage.setItem(STORAGE_ID_KEY, id);
|
||||||
|
|
||||||
|
if (isNewAnnouncement) {
|
||||||
|
sessionStorage.setItem(STORAGE_DISMISS_KEY, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
isNewAnnouncement ||
|
||||||
|
sessionStorage.getItem(STORAGE_DISMISS_KEY) === 'false'
|
||||||
|
) {
|
||||||
|
setClosed(false);
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
if (!content || isClosed) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={styles.announcementBar}
|
||||||
|
style={{backgroundColor, color: textColor}}
|
||||||
|
role="banner">
|
||||||
|
<div
|
||||||
|
className={styles.announcementBarContent}
|
||||||
|
dangerouslySetInnerHTML={{__html: content}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className={styles.announcementBarClose}
|
||||||
|
onClick={handleClose}
|
||||||
|
aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default AnnouncementBar;
|
|
@ -0,0 +1,48 @@
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.announcementBar {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
background-color: #fff;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.announcementBarClose {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 55px;
|
||||||
|
font-size: 25px;
|
||||||
|
padding: 0;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
background: none;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.announcementBarContent {
|
||||||
|
font-size: 85%;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
padding: 5px 0;
|
||||||
|
margin-right: 55px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 576px) {
|
||||||
|
.announcementBarClose {
|
||||||
|
width: 35px;
|
||||||
|
}
|
||||||
|
.announcementBarContent {
|
||||||
|
margin-right: 35px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.announcementBarContent a {
|
||||||
|
color: inherit;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
|
@ -13,6 +13,7 @@ import useBaseUrl from '@docusaurus/useBaseUrl';
|
||||||
|
|
||||||
import ThemeProvider from '@theme/ThemeProvider';
|
import ThemeProvider from '@theme/ThemeProvider';
|
||||||
import TabGroupChoiceProvider from '@theme/TabGroupChoiceProvider';
|
import TabGroupChoiceProvider from '@theme/TabGroupChoiceProvider';
|
||||||
|
import AnnouncementBar from '@theme/AnnouncementBar';
|
||||||
import Navbar from '@theme/Navbar';
|
import Navbar from '@theme/Navbar';
|
||||||
import Footer from '@theme/Footer';
|
import Footer from '@theme/Footer';
|
||||||
|
|
||||||
|
@ -76,6 +77,7 @@ function Layout(props) {
|
||||||
)}
|
)}
|
||||||
<meta name="twitter:card" content="summary_large_image" />
|
<meta name="twitter:card" content="summary_large_image" />
|
||||||
</Head>
|
</Head>
|
||||||
|
<AnnouncementBar />
|
||||||
<Navbar />
|
<Navbar />
|
||||||
<div className="main-wrapper">{children}</div>
|
<div className="main-wrapper">{children}</div>
|
||||||
{!noFooter && <Footer />}
|
{!noFooter && <Footer />}
|
||||||
|
|
|
@ -6,15 +6,13 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, {useCallback, useState} from 'react';
|
import React, {useCallback, useState} from 'react';
|
||||||
|
import classnames from 'classnames';
|
||||||
import Link from '@docusaurus/Link';
|
import Link from '@docusaurus/Link';
|
||||||
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
||||||
import useBaseUrl from '@docusaurus/useBaseUrl';
|
import useBaseUrl from '@docusaurus/useBaseUrl';
|
||||||
|
|
||||||
import SearchBar from '@theme/SearchBar';
|
import SearchBar from '@theme/SearchBar';
|
||||||
import Toggle from '@theme/Toggle';
|
import Toggle from '@theme/Toggle';
|
||||||
|
|
||||||
import classnames from 'classnames';
|
|
||||||
|
|
||||||
import useThemeContext from '@theme/hooks/useThemeContext';
|
import useThemeContext from '@theme/hooks/useThemeContext';
|
||||||
import useHideableNavbar from '@theme/hooks/useHideableNavbar';
|
import useHideableNavbar from '@theme/hooks/useHideableNavbar';
|
||||||
import useLockBodyScroll from '@theme/hooks/useLockBodyScroll';
|
import useLockBodyScroll from '@theme/hooks/useLockBodyScroll';
|
||||||
|
|
|
@ -25,6 +25,10 @@ const useHideableNavbar = hideOnScroll => {
|
||||||
const handleScroll = () => {
|
const handleScroll = () => {
|
||||||
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
|
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
|
||||||
|
|
||||||
|
if (scrollTop === 0) {
|
||||||
|
setIsNavbarVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
if (scrollTop < navbarHeight) {
|
if (scrollTop < navbarHeight) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -39,7 +43,7 @@ const useHideableNavbar = hideOnScroll => {
|
||||||
const documentHeight = document.documentElement.scrollHeight - navbarHeight;
|
const documentHeight = document.documentElement.scrollHeight - navbarHeight;
|
||||||
const windowHeight = window.innerHeight;
|
const windowHeight = window.innerHeight;
|
||||||
|
|
||||||
if (lastScrollTop && scrollTop > lastScrollTop) {
|
if (lastScrollTop && scrollTop >= lastScrollTop) {
|
||||||
setIsNavbarVisible(false);
|
setIsNavbarVisible(false);
|
||||||
} else if (scrollTop + windowHeight < documentHeight) {
|
} else if (scrollTop + windowHeight < documentHeight) {
|
||||||
setIsNavbarVisible(true);
|
setIsNavbarVisible(true);
|
||||||
|
|
|
@ -41,6 +41,25 @@ module.exports = {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Announcement bar
|
||||||
|
|
||||||
|
Sometimes you want to announce something in your website. Just for such a case, you can add an announcement bar. This is a non-fixed and dismissable panel above the navbar.
|
||||||
|
|
||||||
|
```js {4-9} title="docusaurus.config.js"
|
||||||
|
module.exports = {
|
||||||
|
...
|
||||||
|
themeConfig: {
|
||||||
|
announcementBar: {
|
||||||
|
id: 'support_us', // Any value that will identify this message
|
||||||
|
content: 'We are looking to revamp our docs, please fill <a target="_blank" rel="noopener noreferrer" href="#">this survey</a>',
|
||||||
|
backgroundColor: '#fafbfc', // Defaults to `#fff`
|
||||||
|
textColor: '#091E42', // Defaults to `#000`
|
||||||
|
},
|
||||||
|
...
|
||||||
|
},
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Navbar
|
## Navbar
|
||||||
|
|
||||||
### Navbar Title & Logo
|
### Navbar Title & Logo
|
||||||
|
|
|
@ -59,6 +59,13 @@ module.exports = {
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
themeConfig: {
|
themeConfig: {
|
||||||
|
announcementBar: {
|
||||||
|
id: 'supportus',
|
||||||
|
content:
|
||||||
|
'⭐️ If you like Docusaurus, give it a star on <a target="_blank" rel="noopener noreferrer" href="https://github.com/facebook/docusaurus">GitHub</a>! ⭐️',
|
||||||
|
backgroundColor: '#fafbfc',
|
||||||
|
textColor: '#091E42',
|
||||||
|
},
|
||||||
prism: {
|
prism: {
|
||||||
theme: require('prism-react-renderer/themes/github'),
|
theme: require('prism-react-renderer/themes/github'),
|
||||||
darkTheme: require('prism-react-renderer/themes/dracula'),
|
darkTheme: require('prism-react-renderer/themes/dracula'),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue