@docusaurus/theme-classic 0.0.0-4655 → 0.0.0-4658
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/getSwizzleConfig.js +64 -41
- package/lib/theme-classic.d.ts +17 -1
- package/lib/validateThemeConfig.js +4 -13
- package/lib-next/theme/BlogPostAuthor/index.js +18 -6
- package/lib-next/theme/ColorModeToggle/index.js +83 -0
- package/lib-next/theme/ColorModeToggle/styles.module.css +51 -0
- package/lib-next/theme/IconDarkMode/index.js +17 -0
- package/lib-next/theme/IconLightMode/index.js +17 -0
- package/lib-next/theme/Navbar/index.js +3 -3
- package/package.json +13 -13
- package/src/getSwizzleConfig.ts +53 -31
- package/src/theme/BlogPostAuthor/index.tsx +17 -7
- package/src/theme/ColorModeToggle/index.tsx +92 -0
- package/src/theme/ColorModeToggle/styles.module.css +51 -0
- package/src/theme/IconDarkMode/index.tsx +20 -0
- package/src/theme/IconLightMode/index.tsx +20 -0
- package/src/theme/Navbar/index.tsx +3 -3
- package/src/theme-classic.d.ts +17 -1
- package/src/validateThemeConfig.ts +4 -20
- package/lib-next/theme/Toggle/index.js +0 -100
- package/lib-next/theme/Toggle/styles.module.css +0 -106
- package/src/theme/Toggle/index.tsx +0 -117
- package/src/theme/Toggle/styles.module.css +0 -106
|
@@ -6,19 +6,29 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import React from 'react';
|
|
9
|
-
import Link from '@docusaurus/Link';
|
|
9
|
+
import Link, {type Props as LinkProps} from '@docusaurus/Link';
|
|
10
10
|
import type {Props} from '@theme/BlogPostAuthor';
|
|
11
11
|
|
|
12
12
|
import styles from './styles.module.css';
|
|
13
13
|
|
|
14
|
+
function MaybeLink(props: LinkProps): JSX.Element {
|
|
15
|
+
if (props.href) {
|
|
16
|
+
return <Link {...props} />;
|
|
17
|
+
}
|
|
18
|
+
return <>{props.children}</>;
|
|
19
|
+
}
|
|
20
|
+
|
|
14
21
|
export default function BlogPostAuthor({author}: Props): JSX.Element {
|
|
15
|
-
const {name, title, url, imageURL} = author;
|
|
22
|
+
const {name, title, url, imageURL, email} = author;
|
|
23
|
+
const link = url || (email && `mailto:${email}`) || undefined;
|
|
16
24
|
return (
|
|
17
25
|
<div className="avatar margin-bottom--sm">
|
|
18
26
|
{imageURL && (
|
|
19
|
-
<
|
|
20
|
-
<
|
|
21
|
-
|
|
27
|
+
<span className="avatar__photo-link avatar__photo">
|
|
28
|
+
<MaybeLink href={link}>
|
|
29
|
+
<img className={styles.image} src={imageURL} alt={name} />
|
|
30
|
+
</MaybeLink>
|
|
31
|
+
</span>
|
|
22
32
|
)}
|
|
23
33
|
|
|
24
34
|
{name && (
|
|
@@ -28,9 +38,9 @@ export default function BlogPostAuthor({author}: Props): JSX.Element {
|
|
|
28
38
|
itemScope
|
|
29
39
|
itemType="https://schema.org/Person">
|
|
30
40
|
<div className="avatar__name">
|
|
31
|
-
<
|
|
41
|
+
<MaybeLink href={link} itemProp="url">
|
|
32
42
|
<span itemProp="name">{name}</span>
|
|
33
|
-
</
|
|
43
|
+
</MaybeLink>
|
|
34
44
|
</div>
|
|
35
45
|
{title && (
|
|
36
46
|
<small className="avatar__subtitle" itemProp="description">
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import React, {useState, useRef, useEffect} from 'react';
|
|
9
|
+
import type {Props} from '@theme/ColorModeToggle';
|
|
10
|
+
import useIsBrowser from '@docusaurus/useIsBrowser';
|
|
11
|
+
import {translate} from '@docusaurus/Translate';
|
|
12
|
+
import IconLightMode from '@theme/IconLightMode';
|
|
13
|
+
import IconDarkMode from '@theme/IconDarkMode';
|
|
14
|
+
|
|
15
|
+
import clsx from 'clsx';
|
|
16
|
+
import styles from './styles.module.css';
|
|
17
|
+
|
|
18
|
+
function ColorModeToggle({
|
|
19
|
+
className,
|
|
20
|
+
checked: defaultChecked,
|
|
21
|
+
onChange,
|
|
22
|
+
}: Props): JSX.Element {
|
|
23
|
+
const isBrowser = useIsBrowser();
|
|
24
|
+
const [checked, setChecked] = useState(defaultChecked);
|
|
25
|
+
const [focused, setFocused] = useState(false);
|
|
26
|
+
const inputRef = useRef<HTMLInputElement>(null);
|
|
27
|
+
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
setChecked(defaultChecked);
|
|
30
|
+
}, [defaultChecked]);
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<div
|
|
34
|
+
className={clsx(styles.toggle, className, {
|
|
35
|
+
[styles.toggleChecked]: checked,
|
|
36
|
+
[styles.toggleFocused]: focused,
|
|
37
|
+
[styles.toggleDisabled]: !isBrowser,
|
|
38
|
+
})}>
|
|
39
|
+
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events */}
|
|
40
|
+
<div
|
|
41
|
+
className={styles.toggleButton}
|
|
42
|
+
role="button"
|
|
43
|
+
tabIndex={-1}
|
|
44
|
+
onClick={() => inputRef.current?.click()}>
|
|
45
|
+
<IconLightMode
|
|
46
|
+
className={clsx(styles.toggleIcon, styles.lightToggleIcon)}
|
|
47
|
+
/>
|
|
48
|
+
<IconDarkMode
|
|
49
|
+
className={clsx(styles.toggleIcon, styles.darkToggleIcon)}
|
|
50
|
+
/>
|
|
51
|
+
</div>
|
|
52
|
+
|
|
53
|
+
<input
|
|
54
|
+
ref={inputRef}
|
|
55
|
+
checked={checked}
|
|
56
|
+
type="checkbox"
|
|
57
|
+
className={styles.toggleScreenReader}
|
|
58
|
+
aria-label={translate(
|
|
59
|
+
{
|
|
60
|
+
message: 'Switch between dark and light mode (currently {mode})',
|
|
61
|
+
id: 'theme.colorToggle.ariaLabel',
|
|
62
|
+
description: 'The ARIA label for the navbar color mode toggle',
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
mode: checked
|
|
66
|
+
? translate({
|
|
67
|
+
message: 'dark mode',
|
|
68
|
+
id: 'theme.colorToggle.ariaLabel.mode.dark',
|
|
69
|
+
description: 'The name for the dark color mode',
|
|
70
|
+
})
|
|
71
|
+
: translate({
|
|
72
|
+
message: 'light mode',
|
|
73
|
+
id: 'theme.colorToggle.ariaLabel.mode.light',
|
|
74
|
+
description: 'The name for the light color mode',
|
|
75
|
+
}),
|
|
76
|
+
},
|
|
77
|
+
)}
|
|
78
|
+
onChange={onChange}
|
|
79
|
+
onClick={() => setChecked(!checked)}
|
|
80
|
+
onFocus={() => setFocused(true)}
|
|
81
|
+
onBlur={() => setFocused(false)}
|
|
82
|
+
onKeyDown={(e) => {
|
|
83
|
+
if (e.key === 'Enter') {
|
|
84
|
+
inputRef.current?.click();
|
|
85
|
+
}
|
|
86
|
+
}}
|
|
87
|
+
/>
|
|
88
|
+
</div>
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export default React.memo(ColorModeToggle);
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
.toggle {
|
|
9
|
+
position: relative;
|
|
10
|
+
width: 32px;
|
|
11
|
+
height: 32px;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.toggleScreenReader {
|
|
15
|
+
border: 0;
|
|
16
|
+
clip: rect(0 0 0 0);
|
|
17
|
+
height: 1px;
|
|
18
|
+
margin: -1px;
|
|
19
|
+
overflow: hidden;
|
|
20
|
+
position: absolute;
|
|
21
|
+
width: 1px;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.toggleDisabled {
|
|
25
|
+
cursor: not-allowed;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.toggleButton {
|
|
29
|
+
cursor: pointer;
|
|
30
|
+
user-select: none;
|
|
31
|
+
-webkit-tap-highlight-color: transparent;
|
|
32
|
+
align-items: center;
|
|
33
|
+
display: flex;
|
|
34
|
+
justify-content: center;
|
|
35
|
+
width: 100%;
|
|
36
|
+
height: 100%;
|
|
37
|
+
border-radius: 50%;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.toggleButton:hover {
|
|
41
|
+
background-color: #00000010;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
[data-theme='dark'] .toggleButton:hover {
|
|
45
|
+
background-color: #ffffff20;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
[data-theme='light'] .darkToggleIcon,
|
|
49
|
+
[data-theme='dark'] .lightToggleIcon {
|
|
50
|
+
display: none;
|
|
51
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import React from 'react';
|
|
9
|
+
import type {Props} from '@theme/IconDarkMode';
|
|
10
|
+
|
|
11
|
+
export default function IconDarkMode(props: Props): JSX.Element {
|
|
12
|
+
return (
|
|
13
|
+
<svg viewBox="0 0 24 24" width={24} height={24} {...props}>
|
|
14
|
+
<path
|
|
15
|
+
fill="currentColor"
|
|
16
|
+
d="M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"
|
|
17
|
+
/>
|
|
18
|
+
</svg>
|
|
19
|
+
);
|
|
20
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import React from 'react';
|
|
9
|
+
import type {Props} from '@theme/IconLightMode';
|
|
10
|
+
|
|
11
|
+
export default function IconLightMode(props: Props): JSX.Element {
|
|
12
|
+
return (
|
|
13
|
+
<svg viewBox="0 0 24 24" width={24} height={24} {...props}>
|
|
14
|
+
<path
|
|
15
|
+
fill="currentColor"
|
|
16
|
+
d="M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"
|
|
17
|
+
/>
|
|
18
|
+
</svg>
|
|
19
|
+
);
|
|
20
|
+
}
|
|
@@ -9,7 +9,7 @@ import React, {useCallback, useState, useEffect} from 'react';
|
|
|
9
9
|
import clsx from 'clsx';
|
|
10
10
|
import Translate from '@docusaurus/Translate';
|
|
11
11
|
import SearchBar from '@theme/SearchBar';
|
|
12
|
-
import
|
|
12
|
+
import ColorModeToggle from '@theme/ColorModeToggle';
|
|
13
13
|
import {
|
|
14
14
|
useThemeConfig,
|
|
15
15
|
useMobileSecondaryMenuRenderer,
|
|
@@ -171,7 +171,7 @@ function NavbarMobileSidebar({
|
|
|
171
171
|
titleClassName="navbar__title"
|
|
172
172
|
/>
|
|
173
173
|
{!colorModeToggle.disabled && (
|
|
174
|
-
<
|
|
174
|
+
<ColorModeToggle
|
|
175
175
|
className={styles.navbarSidebarToggle}
|
|
176
176
|
checked={colorModeToggle.isDarkTheme}
|
|
177
177
|
onChange={colorModeToggle.toggle}
|
|
@@ -271,7 +271,7 @@ export default function Navbar(): JSX.Element {
|
|
|
271
271
|
<NavbarItem {...item} key={i} />
|
|
272
272
|
))}
|
|
273
273
|
{!colorModeToggle.disabled && (
|
|
274
|
-
<
|
|
274
|
+
<ColorModeToggle
|
|
275
275
|
className={styles.toggle}
|
|
276
276
|
checked={colorModeToggle.isDarkTheme}
|
|
277
277
|
onChange={colorModeToggle.toggle}
|
package/src/theme-classic.d.ts
CHANGED
|
@@ -632,7 +632,7 @@ declare module '@theme/TOCCollapsible' {
|
|
|
632
632
|
export default function TOCCollapsible(props: Props): JSX.Element;
|
|
633
633
|
}
|
|
634
634
|
|
|
635
|
-
declare module '@theme/
|
|
635
|
+
declare module '@theme/ColorModeToggle' {
|
|
636
636
|
import type {SyntheticEvent} from 'react';
|
|
637
637
|
|
|
638
638
|
export interface Props {
|
|
@@ -663,6 +663,14 @@ declare module '@theme/IconArrow' {
|
|
|
663
663
|
export default function IconArrow(props: Props): JSX.Element;
|
|
664
664
|
}
|
|
665
665
|
|
|
666
|
+
declare module '@theme/IconDarkMode' {
|
|
667
|
+
import type {ComponentProps} from 'react';
|
|
668
|
+
|
|
669
|
+
export interface Props extends ComponentProps<'svg'> {}
|
|
670
|
+
|
|
671
|
+
export default function IconDarkMode(props: Props): JSX.Element;
|
|
672
|
+
}
|
|
673
|
+
|
|
666
674
|
declare module '@theme/IconEdit' {
|
|
667
675
|
import type {ComponentProps} from 'react';
|
|
668
676
|
|
|
@@ -671,6 +679,14 @@ declare module '@theme/IconEdit' {
|
|
|
671
679
|
export default function IconEdit(props: Props): JSX.Element;
|
|
672
680
|
}
|
|
673
681
|
|
|
682
|
+
declare module '@theme/IconLightMode' {
|
|
683
|
+
import type {ComponentProps} from 'react';
|
|
684
|
+
|
|
685
|
+
export interface Props extends ComponentProps<'svg'> {}
|
|
686
|
+
|
|
687
|
+
export default function IconLightMode(props: Props): JSX.Element;
|
|
688
|
+
}
|
|
689
|
+
|
|
674
690
|
declare module '@theme/IconMenu' {
|
|
675
691
|
import type {ComponentProps} from 'react';
|
|
676
692
|
|
|
@@ -21,12 +21,6 @@ const DEFAULT_COLOR_MODE_CONFIG = {
|
|
|
21
21
|
defaultMode: 'light',
|
|
22
22
|
disableSwitch: false,
|
|
23
23
|
respectPrefersColorScheme: false,
|
|
24
|
-
switchConfig: {
|
|
25
|
-
darkIcon: '🌜',
|
|
26
|
-
darkIconStyle: {},
|
|
27
|
-
lightIcon: '🌞',
|
|
28
|
-
lightIconStyle: {},
|
|
29
|
-
},
|
|
30
24
|
};
|
|
31
25
|
|
|
32
26
|
export const DEFAULT_CONFIG = {
|
|
@@ -220,20 +214,10 @@ const ColorModeSchema = Joi.object({
|
|
|
220
214
|
respectPrefersColorScheme: Joi.bool().default(
|
|
221
215
|
DEFAULT_COLOR_MODE_CONFIG.respectPrefersColorScheme,
|
|
222
216
|
),
|
|
223
|
-
switchConfig: Joi.
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
darkIconStyle: Joi.object().default(
|
|
228
|
-
DEFAULT_COLOR_MODE_CONFIG.switchConfig.darkIconStyle,
|
|
229
|
-
),
|
|
230
|
-
lightIcon: Joi.string().default(
|
|
231
|
-
DEFAULT_COLOR_MODE_CONFIG.switchConfig.lightIcon,
|
|
232
|
-
),
|
|
233
|
-
lightIconStyle: Joi.object().default(
|
|
234
|
-
DEFAULT_COLOR_MODE_CONFIG.switchConfig.lightIconStyle,
|
|
235
|
-
),
|
|
236
|
-
}).default(DEFAULT_COLOR_MODE_CONFIG.switchConfig),
|
|
217
|
+
switchConfig: Joi.any().forbidden().messages({
|
|
218
|
+
'any.unknown':
|
|
219
|
+
'colorMode.switchConfig is deprecated. If you want to customize the icons for light and dark mode, swizzle IconLightMode, IconDarkMode, or ColorModeToggle instead.',
|
|
220
|
+
}),
|
|
237
221
|
}).default(DEFAULT_COLOR_MODE_CONFIG);
|
|
238
222
|
|
|
239
223
|
// schema can probably be improved
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
-
*
|
|
4
|
-
* This source code is licensed under the MIT license found in the
|
|
5
|
-
* LICENSE file in the root directory of this source tree.
|
|
6
|
-
*/
|
|
7
|
-
import React, {useState, useRef, useEffect, memo} from 'react';
|
|
8
|
-
import {useThemeConfig} from '@docusaurus/theme-common';
|
|
9
|
-
import useIsBrowser from '@docusaurus/useIsBrowser';
|
|
10
|
-
import {translate} from '@docusaurus/Translate';
|
|
11
|
-
import clsx from 'clsx';
|
|
12
|
-
import styles from './styles.module.css'; // Based on react-toggle (https://github.com/aaronshaf/react-toggle/).
|
|
13
|
-
|
|
14
|
-
const ToggleComponent = memo(
|
|
15
|
-
({className, switchConfig, checked: defaultChecked, disabled, onChange}) => {
|
|
16
|
-
const {darkIcon, darkIconStyle, lightIcon, lightIconStyle} = switchConfig;
|
|
17
|
-
const [checked, setChecked] = useState(defaultChecked);
|
|
18
|
-
const [focused, setFocused] = useState(false);
|
|
19
|
-
const inputRef = useRef(null);
|
|
20
|
-
useEffect(() => {
|
|
21
|
-
setChecked(defaultChecked);
|
|
22
|
-
}, [defaultChecked]);
|
|
23
|
-
return (
|
|
24
|
-
<div
|
|
25
|
-
className={clsx(styles.toggle, className, {
|
|
26
|
-
[styles.toggleChecked]: checked,
|
|
27
|
-
[styles.toggleFocused]: focused,
|
|
28
|
-
[styles.toggleDisabled]: disabled,
|
|
29
|
-
})}>
|
|
30
|
-
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events */}
|
|
31
|
-
<div
|
|
32
|
-
className={styles.toggleTrack}
|
|
33
|
-
role="button"
|
|
34
|
-
tabIndex={-1}
|
|
35
|
-
onClick={() => inputRef.current?.click()}>
|
|
36
|
-
<div className={styles.toggleTrackCheck}>
|
|
37
|
-
<span className={styles.toggleIcon} style={darkIconStyle}>
|
|
38
|
-
{darkIcon}
|
|
39
|
-
</span>
|
|
40
|
-
</div>
|
|
41
|
-
<div className={styles.toggleTrackX}>
|
|
42
|
-
<span className={styles.toggleIcon} style={lightIconStyle}>
|
|
43
|
-
{lightIcon}
|
|
44
|
-
</span>
|
|
45
|
-
</div>
|
|
46
|
-
<div className={styles.toggleTrackThumb} />
|
|
47
|
-
</div>
|
|
48
|
-
|
|
49
|
-
<input
|
|
50
|
-
ref={inputRef}
|
|
51
|
-
checked={checked}
|
|
52
|
-
type="checkbox"
|
|
53
|
-
className={styles.toggleScreenReader}
|
|
54
|
-
aria-label={translate(
|
|
55
|
-
{
|
|
56
|
-
message: 'Switch between dark and light mode (currently {mode})',
|
|
57
|
-
id: 'theme.colorToggle.ariaLabel',
|
|
58
|
-
description: 'The ARIA label for the navbar color mode toggle',
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
mode: checked
|
|
62
|
-
? translate({
|
|
63
|
-
message: 'dark mode',
|
|
64
|
-
id: 'theme.colorToggle.ariaLabel.mode.dark',
|
|
65
|
-
description: 'The name for the dark color mode',
|
|
66
|
-
})
|
|
67
|
-
: translate({
|
|
68
|
-
message: 'light mode',
|
|
69
|
-
id: 'theme.colorToggle.ariaLabel.mode.light',
|
|
70
|
-
description: 'The name for the light color mode',
|
|
71
|
-
}),
|
|
72
|
-
},
|
|
73
|
-
)}
|
|
74
|
-
onChange={onChange}
|
|
75
|
-
onClick={() => setChecked(!checked)}
|
|
76
|
-
onFocus={() => setFocused(true)}
|
|
77
|
-
onBlur={() => setFocused(false)}
|
|
78
|
-
onKeyDown={(e) => {
|
|
79
|
-
if (e.key === 'Enter') {
|
|
80
|
-
inputRef.current?.click();
|
|
81
|
-
}
|
|
82
|
-
}}
|
|
83
|
-
/>
|
|
84
|
-
</div>
|
|
85
|
-
);
|
|
86
|
-
},
|
|
87
|
-
);
|
|
88
|
-
export default function Toggle(props) {
|
|
89
|
-
const {
|
|
90
|
-
colorMode: {switchConfig},
|
|
91
|
-
} = useThemeConfig();
|
|
92
|
-
const isBrowser = useIsBrowser();
|
|
93
|
-
return (
|
|
94
|
-
<ToggleComponent
|
|
95
|
-
switchConfig={switchConfig}
|
|
96
|
-
disabled={!isBrowser}
|
|
97
|
-
{...props}
|
|
98
|
-
/>
|
|
99
|
-
);
|
|
100
|
-
}
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
-
*
|
|
4
|
-
* This source code is licensed under the MIT license found in the
|
|
5
|
-
* LICENSE file in the root directory of this source tree.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
.toggle {
|
|
9
|
-
touch-action: pan-x;
|
|
10
|
-
position: relative;
|
|
11
|
-
cursor: pointer;
|
|
12
|
-
user-select: none;
|
|
13
|
-
-webkit-tap-highlight-color: transparent;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
.toggleScreenReader {
|
|
17
|
-
border: 0;
|
|
18
|
-
clip: rect(0 0 0 0);
|
|
19
|
-
height: 1px;
|
|
20
|
-
margin: -1px;
|
|
21
|
-
overflow: hidden;
|
|
22
|
-
position: absolute;
|
|
23
|
-
width: 1px;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
.toggleDisabled {
|
|
27
|
-
cursor: not-allowed;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
.toggleTrack {
|
|
31
|
-
width: 50px;
|
|
32
|
-
height: 24px;
|
|
33
|
-
border-radius: 30px;
|
|
34
|
-
background-color: #4d4d4d;
|
|
35
|
-
transition: all 0.2s ease;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
.toggleTrackCheck {
|
|
39
|
-
position: absolute;
|
|
40
|
-
width: 14px;
|
|
41
|
-
height: 10px;
|
|
42
|
-
top: 0;
|
|
43
|
-
bottom: 0;
|
|
44
|
-
margin: auto 0;
|
|
45
|
-
left: 8px;
|
|
46
|
-
opacity: 0;
|
|
47
|
-
transition: opacity 0.25s ease;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
.toggleChecked .toggleTrackCheck,
|
|
51
|
-
[data-theme='dark'] .toggle .toggleTrackCheck {
|
|
52
|
-
opacity: 1;
|
|
53
|
-
transition: opacity 0.25s ease;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
.toggleTrackX {
|
|
57
|
-
position: absolute;
|
|
58
|
-
width: 10px;
|
|
59
|
-
height: 10px;
|
|
60
|
-
top: 0;
|
|
61
|
-
bottom: 0;
|
|
62
|
-
margin: auto 0;
|
|
63
|
-
right: 10px;
|
|
64
|
-
opacity: 1;
|
|
65
|
-
transition: opacity 0.25s ease;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
.toggleChecked .toggleTrackX,
|
|
69
|
-
[data-theme='dark'] .toggle .toggleTrackX {
|
|
70
|
-
opacity: 0;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
.toggleTrackThumb {
|
|
74
|
-
position: absolute;
|
|
75
|
-
top: 1px;
|
|
76
|
-
left: 1px;
|
|
77
|
-
width: 22px;
|
|
78
|
-
height: 22px;
|
|
79
|
-
border: 1px solid #4d4d4d;
|
|
80
|
-
border-radius: 50%;
|
|
81
|
-
background-color: #fafafa;
|
|
82
|
-
transition: all 0.25s ease;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
.toggleFocused .toggleTrackThumb,
|
|
86
|
-
.toggle:hover .toggleTrackThumb {
|
|
87
|
-
box-shadow: 0 0 2px 3px var(--ifm-color-primary);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/* stylelint-disable-next-line no-descending-specificity */
|
|
91
|
-
.toggleChecked .toggleTrackThumb,
|
|
92
|
-
[data-theme='dark'] .toggle .toggleTrackThumb {
|
|
93
|
-
left: 27px;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
.toggle:active:not(.toggleDisabled) .toggleTrackThumb {
|
|
97
|
-
box-shadow: 0 0 5px 5px var(--ifm-color-primary);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
.toggleIcon {
|
|
101
|
-
align-items: center;
|
|
102
|
-
display: flex;
|
|
103
|
-
height: 10px;
|
|
104
|
-
justify-content: center;
|
|
105
|
-
width: 10px;
|
|
106
|
-
}
|
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
-
*
|
|
4
|
-
* This source code is licensed under the MIT license found in the
|
|
5
|
-
* LICENSE file in the root directory of this source tree.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
import React, {useState, useRef, useEffect, memo} from 'react';
|
|
9
|
-
import type {Props} from '@theme/Toggle';
|
|
10
|
-
import {useThemeConfig, type ColorModeConfig} from '@docusaurus/theme-common';
|
|
11
|
-
import useIsBrowser from '@docusaurus/useIsBrowser';
|
|
12
|
-
import {translate} from '@docusaurus/Translate';
|
|
13
|
-
|
|
14
|
-
import clsx from 'clsx';
|
|
15
|
-
import styles from './styles.module.css';
|
|
16
|
-
|
|
17
|
-
// Based on react-toggle (https://github.com/aaronshaf/react-toggle/).
|
|
18
|
-
const ToggleComponent = memo(
|
|
19
|
-
({
|
|
20
|
-
className,
|
|
21
|
-
switchConfig,
|
|
22
|
-
checked: defaultChecked,
|
|
23
|
-
disabled,
|
|
24
|
-
onChange,
|
|
25
|
-
}: Props & {
|
|
26
|
-
switchConfig: ColorModeConfig['switchConfig'];
|
|
27
|
-
disabled: boolean;
|
|
28
|
-
}): JSX.Element => {
|
|
29
|
-
const {darkIcon, darkIconStyle, lightIcon, lightIconStyle} = switchConfig;
|
|
30
|
-
const [checked, setChecked] = useState(defaultChecked);
|
|
31
|
-
const [focused, setFocused] = useState(false);
|
|
32
|
-
const inputRef = useRef<HTMLInputElement>(null);
|
|
33
|
-
|
|
34
|
-
useEffect(() => {
|
|
35
|
-
setChecked(defaultChecked);
|
|
36
|
-
}, [defaultChecked]);
|
|
37
|
-
|
|
38
|
-
return (
|
|
39
|
-
<div
|
|
40
|
-
className={clsx(styles.toggle, className, {
|
|
41
|
-
[styles.toggleChecked]: checked,
|
|
42
|
-
[styles.toggleFocused]: focused,
|
|
43
|
-
[styles.toggleDisabled]: disabled,
|
|
44
|
-
})}>
|
|
45
|
-
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events */}
|
|
46
|
-
<div
|
|
47
|
-
className={styles.toggleTrack}
|
|
48
|
-
role="button"
|
|
49
|
-
tabIndex={-1}
|
|
50
|
-
onClick={() => inputRef.current?.click()}>
|
|
51
|
-
<div className={styles.toggleTrackCheck}>
|
|
52
|
-
<span className={styles.toggleIcon} style={darkIconStyle}>
|
|
53
|
-
{darkIcon}
|
|
54
|
-
</span>
|
|
55
|
-
</div>
|
|
56
|
-
<div className={styles.toggleTrackX}>
|
|
57
|
-
<span className={styles.toggleIcon} style={lightIconStyle}>
|
|
58
|
-
{lightIcon}
|
|
59
|
-
</span>
|
|
60
|
-
</div>
|
|
61
|
-
<div className={styles.toggleTrackThumb} />
|
|
62
|
-
</div>
|
|
63
|
-
|
|
64
|
-
<input
|
|
65
|
-
ref={inputRef}
|
|
66
|
-
checked={checked}
|
|
67
|
-
type="checkbox"
|
|
68
|
-
className={styles.toggleScreenReader}
|
|
69
|
-
aria-label={translate(
|
|
70
|
-
{
|
|
71
|
-
message: 'Switch between dark and light mode (currently {mode})',
|
|
72
|
-
id: 'theme.colorToggle.ariaLabel',
|
|
73
|
-
description: 'The ARIA label for the navbar color mode toggle',
|
|
74
|
-
},
|
|
75
|
-
{
|
|
76
|
-
mode: checked
|
|
77
|
-
? translate({
|
|
78
|
-
message: 'dark mode',
|
|
79
|
-
id: 'theme.colorToggle.ariaLabel.mode.dark',
|
|
80
|
-
description: 'The name for the dark color mode',
|
|
81
|
-
})
|
|
82
|
-
: translate({
|
|
83
|
-
message: 'light mode',
|
|
84
|
-
id: 'theme.colorToggle.ariaLabel.mode.light',
|
|
85
|
-
description: 'The name for the light color mode',
|
|
86
|
-
}),
|
|
87
|
-
},
|
|
88
|
-
)}
|
|
89
|
-
onChange={onChange}
|
|
90
|
-
onClick={() => setChecked(!checked)}
|
|
91
|
-
onFocus={() => setFocused(true)}
|
|
92
|
-
onBlur={() => setFocused(false)}
|
|
93
|
-
onKeyDown={(e) => {
|
|
94
|
-
if (e.key === 'Enter') {
|
|
95
|
-
inputRef.current?.click();
|
|
96
|
-
}
|
|
97
|
-
}}
|
|
98
|
-
/>
|
|
99
|
-
</div>
|
|
100
|
-
);
|
|
101
|
-
},
|
|
102
|
-
);
|
|
103
|
-
|
|
104
|
-
export default function Toggle(props: Props): JSX.Element {
|
|
105
|
-
const {
|
|
106
|
-
colorMode: {switchConfig},
|
|
107
|
-
} = useThemeConfig();
|
|
108
|
-
const isBrowser = useIsBrowser();
|
|
109
|
-
|
|
110
|
-
return (
|
|
111
|
-
<ToggleComponent
|
|
112
|
-
switchConfig={switchConfig}
|
|
113
|
-
disabled={!isBrowser}
|
|
114
|
-
{...props}
|
|
115
|
-
/>
|
|
116
|
-
);
|
|
117
|
-
}
|