mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-25 06:56:56 +02:00
refactor(v2): toggle data-theme with vanilla js instead of react helmet (#2127)
* refactor(v2): toggle data-theme with vanilla js instead of react helmet * use document documentElement
This commit is contained in:
parent
ee00ecf569
commit
33622c5347
4 changed files with 114 additions and 116 deletions
|
@ -12,7 +12,7 @@ const path = require('path');
|
||||||
const storageKey = 'theme';
|
const storageKey = 'theme';
|
||||||
const noFlash = `(function() {
|
const noFlash = `(function() {
|
||||||
function setDataThemeAttribute(theme) {
|
function setDataThemeAttribute(theme) {
|
||||||
document.querySelector('html').setAttribute('data-theme', theme);
|
document.documentElement.setAttribute('data-theme', theme);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPreferredTheme() {
|
function getPreferredTheme() {
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
|
|
||||||
import React, {useCallback, useState} from 'react';
|
import React, {useCallback, useState} from 'react';
|
||||||
import Link from '@docusaurus/Link';
|
import Link from '@docusaurus/Link';
|
||||||
import Head from '@docusaurus/Head';
|
|
||||||
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
||||||
import useBaseUrl from '@docusaurus/useBaseUrl';
|
import useBaseUrl from '@docusaurus/useBaseUrl';
|
||||||
|
|
||||||
|
@ -68,122 +67,116 @@ function Navbar() {
|
||||||
|
|
||||||
const logoUrl = useBaseUrl(logo.src);
|
const logoUrl = useBaseUrl(logo.src);
|
||||||
return (
|
return (
|
||||||
<>
|
<nav
|
||||||
<Head>
|
ref={navbarRef}
|
||||||
{/* TODO: Do not assume that it is in english language */}
|
className={classnames('navbar', 'navbar--light', 'navbar--fixed-top', {
|
||||||
<html lang="en" data-theme={theme} />
|
'navbar-sidebar--show': sidebarShown,
|
||||||
</Head>
|
[styles.navbarHideable]: hideOnScroll,
|
||||||
<nav
|
[styles.navbarHidden]: !isNavbarVisible,
|
||||||
ref={navbarRef}
|
})}>
|
||||||
className={classnames('navbar', 'navbar--light', 'navbar--fixed-top', {
|
<div className="navbar__inner">
|
||||||
'navbar-sidebar--show': sidebarShown,
|
<div className="navbar__items">
|
||||||
[styles.navbarHideable]: hideOnScroll,
|
<div
|
||||||
[styles.navbarHidden]: !isNavbarVisible,
|
aria-label="Navigation bar toggle"
|
||||||
})}>
|
className="navbar__toggle"
|
||||||
<div className="navbar__inner">
|
role="button"
|
||||||
<div className="navbar__items">
|
tabIndex={0}
|
||||||
<div
|
onClick={showSidebar}
|
||||||
aria-label="Navigation bar toggle"
|
onKeyDown={showSidebar}>
|
||||||
className="navbar__toggle"
|
<svg
|
||||||
role="button"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
tabIndex={0}
|
width="30"
|
||||||
onClick={showSidebar}
|
height="30"
|
||||||
onKeyDown={showSidebar}>
|
viewBox="0 0 30 30"
|
||||||
<svg
|
role="img"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
focusable="false">
|
||||||
width="30"
|
<title>Menu</title>
|
||||||
height="30"
|
<path
|
||||||
viewBox="0 0 30 30"
|
stroke="currentColor"
|
||||||
role="img"
|
strokeLinecap="round"
|
||||||
focusable="false">
|
strokeMiterlimit="10"
|
||||||
<title>Menu</title>
|
strokeWidth="2"
|
||||||
<path
|
d="M4 7h22M4 15h22M4 23h22"
|
||||||
stroke="currentColor"
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeMiterlimit="10"
|
|
||||||
strokeWidth="2"
|
|
||||||
d="M4 7h22M4 15h22M4 23h22"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
<Link className="navbar__brand" to={baseUrl}>
|
|
||||||
{logo != null && (
|
|
||||||
<img className="navbar__logo" src={logoUrl} alt={logo.alt} />
|
|
||||||
)}
|
|
||||||
{title != null && (
|
|
||||||
<strong
|
|
||||||
className={isSearchBarExpanded ? styles.hideLogoText : ''}>
|
|
||||||
{title}
|
|
||||||
</strong>
|
|
||||||
)}
|
|
||||||
</Link>
|
|
||||||
{links
|
|
||||||
.filter(linkItem => linkItem.position !== 'right')
|
|
||||||
.map((linkItem, i) => (
|
|
||||||
<NavLink {...linkItem} key={i} />
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
<div className="navbar__items navbar__items--right">
|
|
||||||
{links
|
|
||||||
.filter(linkItem => linkItem.position === 'right')
|
|
||||||
.map((linkItem, i) => (
|
|
||||||
<NavLink {...linkItem} key={i} />
|
|
||||||
))}
|
|
||||||
{!disableDarkMode && (
|
|
||||||
<Toggle
|
|
||||||
className={styles.displayOnlyInLargeViewport}
|
|
||||||
aria-label="Dark mode toggle"
|
|
||||||
checked={theme === 'dark'}
|
|
||||||
onChange={onToggleChange}
|
|
||||||
/>
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<Link className="navbar__brand" to={baseUrl}>
|
||||||
|
{logo != null && (
|
||||||
|
<img className="navbar__logo" src={logoUrl} alt={logo.alt} />
|
||||||
)}
|
)}
|
||||||
<SearchBar
|
{title != null && (
|
||||||
handleSearchBarToggle={setIsSearchBarExpanded}
|
<strong
|
||||||
isSearchBarExpanded={isSearchBarExpanded}
|
className={isSearchBarExpanded ? styles.hideLogoText : ''}>
|
||||||
|
{title}
|
||||||
|
</strong>
|
||||||
|
)}
|
||||||
|
</Link>
|
||||||
|
{links
|
||||||
|
.filter(linkItem => linkItem.position !== 'right')
|
||||||
|
.map((linkItem, i) => (
|
||||||
|
<NavLink {...linkItem} key={i} />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
<div className="navbar__items navbar__items--right">
|
||||||
|
{links
|
||||||
|
.filter(linkItem => linkItem.position === 'right')
|
||||||
|
.map((linkItem, i) => (
|
||||||
|
<NavLink {...linkItem} key={i} />
|
||||||
|
))}
|
||||||
|
{!disableDarkMode && (
|
||||||
|
<Toggle
|
||||||
|
className={styles.displayOnlyInLargeViewport}
|
||||||
|
aria-label="Dark mode toggle"
|
||||||
|
checked={theme === 'dark'}
|
||||||
|
onChange={onToggleChange}
|
||||||
/>
|
/>
|
||||||
</div>
|
)}
|
||||||
|
<SearchBar
|
||||||
|
handleSearchBarToggle={setIsSearchBarExpanded}
|
||||||
|
isSearchBarExpanded={isSearchBarExpanded}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div
|
</div>
|
||||||
role="presentation"
|
<div
|
||||||
className="navbar-sidebar__backdrop"
|
role="presentation"
|
||||||
onClick={() => {
|
className="navbar-sidebar__backdrop"
|
||||||
setSidebarShown(false);
|
onClick={() => {
|
||||||
}}
|
setSidebarShown(false);
|
||||||
/>
|
}}
|
||||||
<div className="navbar-sidebar">
|
/>
|
||||||
<div className="navbar-sidebar__brand">
|
<div className="navbar-sidebar">
|
||||||
<Link className="navbar__brand" onClick={hideSidebar} to={baseUrl}>
|
<div className="navbar-sidebar__brand">
|
||||||
{logo != null && (
|
<Link className="navbar__brand" onClick={hideSidebar} to={baseUrl}>
|
||||||
<img className="navbar__logo" src={logoUrl} alt={logo.alt} />
|
{logo != null && (
|
||||||
)}
|
<img className="navbar__logo" src={logoUrl} alt={logo.alt} />
|
||||||
{title != null && <strong>{title}</strong>}
|
|
||||||
</Link>
|
|
||||||
{!disableDarkMode && sidebarShown && (
|
|
||||||
<Toggle
|
|
||||||
aria-label="Dark mode toggle in sidebar"
|
|
||||||
checked={theme === 'dark'}
|
|
||||||
onChange={onToggleChange}
|
|
||||||
/>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
{title != null && <strong>{title}</strong>}
|
||||||
<div className="navbar-sidebar__items">
|
</Link>
|
||||||
<div className="menu">
|
{!disableDarkMode && sidebarShown && (
|
||||||
<ul className="menu__list">
|
<Toggle
|
||||||
{links.map((linkItem, i) => (
|
aria-label="Dark mode toggle in sidebar"
|
||||||
<li className="menu__list-item" key={i}>
|
checked={theme === 'dark'}
|
||||||
<NavLink
|
onChange={onToggleChange}
|
||||||
className="menu__link"
|
/>
|
||||||
{...linkItem}
|
)}
|
||||||
onClick={hideSidebar}
|
</div>
|
||||||
/>
|
<div className="navbar-sidebar__items">
|
||||||
</li>
|
<div className="menu">
|
||||||
))}
|
<ul className="menu__list">
|
||||||
</ul>
|
{links.map((linkItem, i) => (
|
||||||
</div>
|
<li className="menu__list-item" key={i}>
|
||||||
|
<NavLink
|
||||||
|
className="menu__link"
|
||||||
|
{...linkItem}
|
||||||
|
onClick={hideSidebar}
|
||||||
|
/>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</div>
|
||||||
</>
|
</nav>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,9 +9,14 @@ import * as React from 'react';
|
||||||
const useTheme = () => {
|
const useTheme = () => {
|
||||||
const [theme, setTheme] = React.useState(
|
const [theme, setTheme] = React.useState(
|
||||||
typeof document !== 'undefined'
|
typeof document !== 'undefined'
|
||||||
? document.querySelector('html').getAttribute('data-theme')
|
? document.documentElement.getAttribute('data-theme')
|
||||||
: '',
|
: '',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
document.documentElement.setAttribute('data-theme', theme);
|
||||||
|
}, [theme]);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
try {
|
try {
|
||||||
const localStorageTheme = localStorage.getItem('theme');
|
const localStorageTheme = localStorage.getItem('theme');
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, {useEffect} from 'react';
|
import React, {useEffect, useRef} from 'react';
|
||||||
import {NavLink} from 'react-router-dom';
|
import {NavLink} from 'react-router-dom';
|
||||||
|
|
||||||
const internalRegex = /^\/(?!\/)/;
|
const internalRegex = /^\/(?!\/)/;
|
||||||
|
@ -14,7 +14,7 @@ function Link(props) {
|
||||||
const {to, href} = props;
|
const {to, href} = props;
|
||||||
const targetLink = to || href;
|
const targetLink = to || href;
|
||||||
const isInternal = internalRegex.test(targetLink);
|
const isInternal = internalRegex.test(targetLink);
|
||||||
let preloaded = false;
|
const preloaded = useRef(false);
|
||||||
|
|
||||||
const IOSupported =
|
const IOSupported =
|
||||||
typeof window !== 'undefined' && 'IntersectionObserver' in window;
|
typeof window !== 'undefined' && 'IntersectionObserver' in window;
|
||||||
|
@ -48,9 +48,9 @@ function Link(props) {
|
||||||
};
|
};
|
||||||
|
|
||||||
const onMouseEnter = () => {
|
const onMouseEnter = () => {
|
||||||
if (!preloaded) {
|
if (!preloaded.current) {
|
||||||
window.docusaurus.preload(targetLink);
|
window.docusaurus.preload(targetLink);
|
||||||
preloaded = true;
|
preloaded.current = true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue