Skip to content

Commit ee1d708

Browse files
committed
feat: add dark theme
1 parent a214b9a commit ee1d708

35 files changed

Lines changed: 594 additions & 164 deletions

.stylelintrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"declaration-property-value-allowed-list": {
2020
"/color/": ["/var/", "currentColor", "transparent", "unset", "inherit"],
2121
"font-size": ["/var/", "/[0-9]+em$/", "unset", "inherit"],
22-
"border-radius": ["/var/", "50%", "0"]
22+
"border-radius": ["/var/", "50%", "0", "inherit"]
2323
},
2424
"declaration-property-value-disallowed-list": {
2525
"transition": ["/all/"]

packages/site/src/app/App.tsx

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import type { DLang, DTheme } from '@react-devui/ui/hooks/d-config';
2+
13
import React, { useCallback, useEffect, useMemo, useState } from 'react';
24
import { useTranslation } from 'react-i18next';
35
import { useLocation } from 'react-router-dom';
@@ -13,6 +15,8 @@ import { AppRoutes } from './routes/Routes';
1315
export interface AppContextData {
1416
menuOpen: boolean;
1517
pageMounted: boolean;
18+
theme: DTheme;
19+
changeTheme: (theme: DTheme) => void;
1620
onMount: () => void;
1721
onMenuOpenChange: (open: boolean) => void;
1822
}
@@ -24,6 +28,7 @@ export function App() {
2428

2529
const [menuOpen, setMenuOpen] = useState(false);
2630
const [pageMounted, setPageMounted] = useState(false);
31+
const [theme, setTheme] = useState<DTheme>(() => (localStorage.getItem('theme') as DTheme) ?? 'light');
2732

2833
const [mainEl, setMainEl] = useState<HTMLElement | null>(null);
2934
const mainRef = useCallback(
@@ -56,6 +61,14 @@ export function App() {
5661
}
5762
}, [asyncCapture, mainEl]);
5863

64+
useEffect(() => {
65+
const el = document.createElement('div');
66+
el.setAttribute('style', 'position: absolute;top: -999px;left: -999px;overflow: scroll;width: 100px;height: 100px;');
67+
document.body.appendChild(el);
68+
document.body.classList.toggle('scrollbar-dark', theme === 'dark' && el.clientHeight < 100);
69+
document.body.removeChild(el);
70+
}, [theme]);
71+
5972
const location = useLocation();
6073
useEffect(() => {
6174
NotificationService.closeAll(false);
@@ -66,6 +79,11 @@ export function App() {
6679
() => ({
6780
menuOpen,
6881
pageMounted,
82+
theme,
83+
changeTheme: (theme) => {
84+
setTheme(theme);
85+
localStorage.setItem('theme', theme);
86+
},
6987
onMount: () => {
7088
setPageMounted(true);
7189
if (mainEl) {
@@ -82,11 +100,11 @@ export function App() {
82100
setMenuOpen(open);
83101
},
84102
}),
85-
[mainEl, menuOpen, pageMounted, setMenuOpen, setPageMounted]
103+
[mainEl, menuOpen, pageMounted, theme]
86104
);
87105

88106
return (
89-
<DRoot i18n={{ lang: i18n.language as 'en-US' | 'zh-Hant' }} icons={icons} contentSelector="main .app-route-article">
107+
<DRoot theme={theme} i18n={{ lang: i18n.language as DLang }} icons={icons} contentSelector="main .app-route-article">
90108
<AppContext.Provider value={contextValue}>
91109
<AppHeader />
92110
<AppSidebar />

packages/site/src/app/components/header/Header.scss

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@
7070
height: 64px;
7171
padding: 0 20px;
7272

73-
background-color: var(--d-background-color);
73+
background-color: var(--app-header-background-color);
7474

7575
&.is-shadow {
7676
box-shadow: 0 2px 8px 0 var(--d-shadow-color);
@@ -94,26 +94,11 @@
9494
@include font-size(1.5rem);
9595
}
9696

97-
.app-header__github {
98-
display: inline-flex;
99-
align-items: center;
100-
justify-content: center;
101-
width: 32px;
102-
height: 32px;
97+
.app-header__button {
10398
margin-left: 12px;
104-
padding: 0;
99+
105100
border: 1px solid var(--d-border-color);
106101
/* stylelint-disable-next-line declaration-property-value-allowed-list */
107102
border-radius: 8px;
108103
}
109-
110-
.app-header__github-icon {
111-
width: 20px;
112-
height: 20px;
113-
114-
/* stylelint-disable-next-line */
115-
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIGlkPSJMYXllcl8xIiB4PSIwcHgiIHk9IjBweCIgd2lkdGg9IjQwcHgiIGhlaWdodD0iNDBweCIgdmlld0JveD0iMTIgMTIgNDAgNDAiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMTIgMTIgNDAgNDAiIHhtbDpzcGFjZT0icHJlc2VydmUiPjxwYXRoIGZpbGw9IiMzMzMzMzMiIGQ9Ik0zMiAxMy40Yy0xMC41IDAtMTkgOC41LTE5IDE5YzAgOC40IDUuNSAxNS41IDEzIDE4YzEgMC4yIDEuMy0wLjQgMS4zLTAuOWMwLTAuNSAwLTEuNyAwLTMuMiBjLTUuMyAxLjEtNi40LTIuNi02LjQtMi42QzIwIDQxLjYgMTguOCA0MSAxOC44IDQxYy0xLjctMS4yIDAuMS0xLjEgMC4xLTEuMWMxLjkgMC4xIDIuOSAyIDIuOSAyYzEuNyAyLjkgNC41IDIuMSA1LjUgMS42IGMwLjItMS4yIDAuNy0yLjEgMS4yLTIuNmMtNC4yLTAuNS04LjctMi4xLTguNy05LjRjMC0yLjEgMC43LTMuNyAyLTUuMWMtMC4yLTAuNS0wLjgtMi40IDAuMi01YzAgMCAxLjYtMC41IDUuMiAyIGMxLjUtMC40IDMuMS0wLjcgNC44LTAuN2MxLjYgMCAzLjMgMC4yIDQuNyAwLjdjMy42LTIuNCA1LjItMiA1LjItMmMxIDIuNiAwLjQgNC42IDAuMiA1YzEuMiAxLjMgMiAzIDIgNS4xYzAgNy4zLTQuNSA4LjktOC43IDkuNCBjMC43IDAuNiAxLjMgMS43IDEuMyAzLjVjMCAyLjYgMCA0LjYgMCA1LjJjMCAwLjUgMC40IDEuMSAxLjMgMC45YzcuNS0yLjYgMTMtOS43IDEzLTE4LjFDNTEgMjEuOSA0Mi41IDEzLjQgMzIgMTMuNHoiLz48L3N2Zz4=);
116-
background-repeat: no-repeat;
117-
background-size: 100% 100%;
118-
}
119104
}

packages/site/src/app/components/header/Header.tsx

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { useCallback } from 'react';
22
import { useTranslation } from 'react-i18next';
33

4-
import { DButton, DRow } from '@react-devui/ui';
4+
import { DButton, DIcon, DRow } from '@react-devui/ui';
55
import { useCustomContext } from '@react-devui/ui/hooks';
66
import { getClassName } from '@react-devui/ui/utils';
77

@@ -11,16 +11,16 @@ import './Header.scss';
1111
export function AppHeader() {
1212
const { i18n } = useTranslation();
1313

14-
const [{ menuOpen = false, onMenuOpenChange }] = useCustomContext(AppContext);
14+
const [{ theme, changeTheme: _changeTheme, menuOpen = false, onMenuOpenChange }] = useCustomContext(AppContext);
1515

1616
const changeLanguage = useCallback(() => {
17-
if (i18n.language === 'en-US') {
18-
i18n.changeLanguage('zh-Hant');
19-
} else {
20-
i18n.changeLanguage('en-US');
21-
}
17+
i18n.changeLanguage(i18n.language === 'en-US' ? 'zh-Hant' : 'en-US');
2218
}, [i18n]);
2319

20+
const changeTheme = useCallback(() => {
21+
_changeTheme?.(theme === 'light' ? 'dark' : 'light');
22+
}, [_changeTheme, theme]);
23+
2424
return (
2525
<header className="app-header is-shadow">
2626
<DRow
@@ -50,10 +50,41 @@ export function AppHeader() {
5050
<DButton className="app-header__language" dType="secondary" onClick={changeLanguage}>
5151
{i18n.language === 'en-US' ? '中 文' : 'English'}
5252
</DButton>
53+
<DButton
54+
className="app-header__button"
55+
dType="text"
56+
dIcon={
57+
<DIcon viewBox="0 0 24 24" dSize={24}>
58+
{theme === 'light' ? (
59+
<path d="M12 23C18.0751 23 23 18.0751 23 12C23 5.92487 18.0751 1 12 1C5.92487 1 1 5.92487 1 12C1 18.0751 5.92487 23 12 23ZM17 15C17.476 15 17.9408 14.9525 18.3901 14.862C17.296 17.3011 14.8464 19 12 19C8.13401 19 5 15.866 5 12C5 8.60996 7.40983 5.78277 10.6099 5.13803C10.218 6.01173 10 6.98041 10 8C10 11.866 13.134 15 17 15Z"></path>
60+
) : (
61+
<>
62+
<path d="M10.5 1.5C10.5 0.671573 11.1716 0 12 0C12.8284 0 13.5 0.671573 13.5 1.5V2.5C13.5 3.32843 12.8284 4 12 4C11.1716 4 10.5 3.32843 10.5 2.5V1.5Z"></path>
63+
<path d="M10.5 21.5C10.5 20.6716 11.1716 20 12 20C12.8284 20 13.5 20.6716 13.5 21.5V22.5C13.5 23.3284 12.8284 24 12 24C11.1716 24 10.5 23.3284 10.5 22.5V21.5Z"></path>
64+
<path d="M24 12C24 11.1716 23.3284 10.5 22.5 10.5H21.5C20.6716 10.5 20 11.1716 20 12C20 12.8284 20.6716 13.5 21.5 13.5H22.5C23.3284 13.5 24 12.8284 24 12Z"></path>
65+
<path d="M2.5 10.5C3.32843 10.5 4 11.1716 4 12C4 12.8284 3.32843 13.5 2.5 13.5H1.5C0.671573 13.5 0 12.8284 0 12C0 11.1716 0.671573 10.5 1.5 10.5H2.5Z"></path>
66+
<path d="M20.4853 3.51472C19.8995 2.92893 18.9497 2.92893 18.364 3.51472L17.6569 4.22182C17.0711 4.80761 17.0711 5.75736 17.6569 6.34314C18.2426 6.92893 19.1924 6.92893 19.7782 6.34314L20.4853 5.63604C21.0711 5.05025 21.0711 4.1005 20.4853 3.51472Z"></path>
67+
<path d="M4.22181 17.6569C4.8076 17.0711 5.75734 17.0711 6.34313 17.6569C6.92892 18.2426 6.92892 19.1924 6.34313 19.7782L5.63602 20.4853C5.05024 21.0711 4.10049 21.0711 3.5147 20.4853C2.92892 19.8995 2.92892 18.9497 3.5147 18.364L4.22181 17.6569Z"></path>
68+
<path d="M3.5147 3.51472C2.92891 4.1005 2.92891 5.05025 3.5147 5.63604L4.22181 6.34315C4.80759 6.92893 5.75734 6.92893 6.34313 6.34315C6.92891 5.75736 6.92891 4.80761 6.34313 4.22183L5.63602 3.51472C5.05023 2.92893 4.10049 2.92893 3.5147 3.51472Z"></path>
69+
<path d="M17.6569 19.7782C17.0711 19.1924 17.0711 18.2426 17.6569 17.6569C18.2426 17.0711 19.1924 17.0711 19.7782 17.6569L20.4853 18.364C21.0711 18.9497 21.0711 19.8995 20.4853 20.4853C19.8995 21.0711 18.9497 21.0711 18.364 20.4853L17.6569 19.7782Z"></path>
70+
<path d="M12 19C15.866 19 19 15.866 19 12C19 8.13401 15.866 5 12 5C8.13401 5 5 8.13401 5 12C5 15.866 8.13401 19 12 19Z"></path>
71+
</>
72+
)}
73+
</DIcon>
74+
}
75+
onClick={changeTheme}
76+
></DButton>
5377
<a href="//github.com/xiejay97/react-devui" target="_blank" rel="noreferrer">
54-
<DButton className="app-header__github" dType="text">
55-
<span className="app-header__github-icon"></span>
56-
</DButton>
78+
<DButton
79+
className="app-header__button"
80+
dType="text"
81+
dIcon={
82+
<DIcon viewBox="0 0 24 24" dSize={24}>
83+
<path d="M12.0101 1C5.92171 1 1 5.92171 1 12.0101C1 16.8771 4.15354 20.9967 8.5284 22.455C9.07526 22.5644 9.27577 22.218 9.27577 21.9264C9.27577 21.6712 9.25754 20.7962 9.25754 19.8848C6.19514 20.541 5.55714 18.5723 5.55714 18.5723C5.06497 17.2963 4.33583 16.9682 4.33583 16.9682C3.33326 16.2938 4.40874 16.2938 4.40874 16.2938C5.52069 16.3667 6.104 17.4239 6.104 17.4239C7.08834 19.101 8.67423 18.627 9.31223 18.3354C9.40337 17.6245 9.69503 17.1323 10.0049 16.8589C7.56229 16.6037 4.99206 15.6558 4.99206 11.4267C4.99206 10.2237 5.42954 9.23931 6.12223 8.47371C6.01286 8.20028 5.63006 7.07011 6.2316 5.55714C6.2316 5.55714 7.16126 5.26548 9.25754 6.68731C10.1325 6.45034 11.0804 6.32274 12.0101 6.32274C12.9397 6.32274 13.8876 6.45034 14.7626 6.68731C16.8589 5.26548 17.7885 5.55714 17.7885 5.55714C18.3901 7.07011 18.0073 8.20028 17.8979 8.47371C18.6088 9.23931 19.0281 10.2237 19.0281 11.4267C19.0281 15.6558 16.4578 16.5854 13.997 16.8589C14.398 17.2052 14.7443 17.8614 14.7443 18.9004C14.7443 20.377 14.7261 21.5618 14.7261 21.9264C14.7261 22.218 14.9266 22.5644 15.4735 22.455C19.8483 20.9967 23.0019 16.8771 23.0019 12.0101C23.0201 5.92171 18.0802 1 12.0101 1Z"></path>
84+
<path d="M5.17419 16.8042C5.15596 16.8589 5.06482 16.8771 4.99191 16.8406C4.91899 16.8042 4.86431 16.7313 4.90076 16.6766C4.91899 16.6219 5.01014 16.6037 5.08305 16.6401C5.15596 16.6766 5.19242 16.7495 5.17419 16.8042ZM5.61168 17.2964C5.55699 17.351 5.44762 17.3146 5.39294 17.2417C5.32002 17.1688 5.30179 17.0594 5.35648 17.0047C5.41116 16.95 5.50231 16.9865 5.57522 17.0594C5.64814 17.1505 5.66636 17.2599 5.61168 17.2964ZM6.04916 17.9344C5.97625 17.989 5.86688 17.9344 5.81219 17.8432C5.73928 17.7521 5.73928 17.6245 5.81219 17.588C5.88511 17.5333 5.99448 17.588 6.04916 17.6792C6.12208 17.7703 6.12208 17.8797 6.04916 17.9344ZM6.65071 18.5541C6.59602 18.627 6.46842 18.6088 6.35905 18.5177C6.26791 18.4265 6.23145 18.2989 6.30436 18.2442C6.35905 18.1713 6.48665 18.1896 6.59602 18.2807C6.68716 18.3536 6.70539 18.4812 6.65071 18.5541ZM7.47099 18.9005C7.45276 18.9916 7.32516 19.0281 7.19756 18.9916C7.06996 18.9552 6.99705 18.8458 7.01528 18.7729C7.03351 18.6817 7.16111 18.6453 7.28871 18.6817C7.41631 18.7182 7.48922 18.8093 7.47099 18.9005ZM8.36419 18.9734C8.36419 19.0645 8.25482 19.1374 8.12722 19.1374C7.99962 19.1374 7.89025 19.0645 7.89025 18.9734C7.89025 18.8822 7.99962 18.8093 8.12722 18.8093C8.25482 18.8093 8.36419 18.8822 8.36419 18.9734ZM9.20271 18.8276C9.22093 18.9187 9.12979 19.0098 9.00219 19.0281C8.87459 19.0463 8.76522 18.9916 8.74699 18.9005C8.72876 18.8093 8.81991 18.7182 8.94751 18.7C9.07511 18.6817 9.18448 18.7364 9.20271 18.8276Z"></path>
85+
</DIcon>
86+
}
87+
></DButton>
5788
</a>
5889
</header>
5990
);

packages/site/src/app/components/route/component/DemoBox.scss

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
.app-demo-box {
44
border: 1px solid var(--d-divider-color);
55

6+
background-color: var(--app-demo-box-background-color);
7+
68
&.is-active {
79
border-color: var(--d-color-primary);
810
}
@@ -35,7 +37,7 @@
3537

3638
padding: 1px 8px;
3739

38-
background-color: var(--d-background-color);
40+
background-color: var(--app-demo-box-background-color);
3941
}
4042

4143
.app-demo-box__description {

packages/site/src/app/styles/_app.scss

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* stylelint-disable selector-id-pattern */
1+
/* stylelint-disable declaration-property-value-allowed-list */
22
*,
33
*::before,
44
*::after {
@@ -15,10 +15,8 @@ body {
1515
line-height: 1.5;
1616
text-align: null;
1717

18-
/* stylelint-disable-next-line declaration-property-value-allowed-list */
19-
background-color: white; // 2
18+
background-color: #fff; // 2
2019
text-size-adjust: 100%; // 3
21-
/* stylelint-disable-next-line declaration-property-value-allowed-list */
2220
-webkit-tap-highlight-color: rgb(0 0 0 / 0%); // 4
2321

2422
@include font-size(1rem);
@@ -100,7 +98,6 @@ pre code.hljs {
10098
code:not(pre > code) {
10199
margin: 0 1px;
102100
padding: 4px 6px;
103-
/* stylelint-disable-next-line declaration-property-value-allowed-list */
104101
border-radius: 2px;
105102

106103
font-family: Consolas, Menlo, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
@@ -235,7 +232,6 @@ h3 {
235232
width: 160px;
236233
height: 40px;
237234

238-
/* stylelint-disable-next-line declaration-property-value-allowed-list */
239235
color: #fff;
240236

241237
background-color: var(--d-color-primary);
@@ -271,7 +267,6 @@ h3 {
271267
justify-content: center;
272268
height: 48px;
273269

274-
/* stylelint-disable-next-line declaration-property-value-allowed-list */
275270
color: #fff;
276271

277272
background-color: var(--d-color-primary);
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/* stylelint-disable declaration-property-value-allowed-list */
2-
32
:root {
43
--app-th-background-color: #f9f9f9;
54
--app-code-background-color: #f2f4f5;
5+
--app-demo-box-background-color: #fff;
6+
--app-header-background-color: #fff;
67
}

packages/site/src/app/styles/index.scss

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
@use 'sass:color';
21
@import 'variables';
32

43
@import 'app';

0 commit comments

Comments
 (0)