From c501898d5fa4ec68f2330c8b618cdf31e0f5a69c Mon Sep 17 00:00:00 2001 From: GyDi Date: Thu, 9 Dec 2021 23:28:57 +0800 Subject: [PATCH] feat: support dark mode --- package.json | 4 +- src/assets/styles/index.scss | 4 -- src/assets/styles/layout.scss | 15 ++--- src/components/list-item-link.tsx | 37 ++++++++++-- src/components/palette-switch.tsx | 51 +++++++++++++++++ src/main.tsx | 21 +------ src/pages/_layout.tsx | 93 ++++++++++++++++++++----------- src/pages/setting.tsx | 21 ++++++- src/states/setting.ts | 6 ++ 9 files changed, 184 insertions(+), 68 deletions(-) create mode 100644 src/components/palette-switch.tsx create mode 100644 src/states/setting.ts diff --git a/package.json b/package.json index f81c005..2ddf6be 100644 --- a/package.json +++ b/package.json @@ -17,9 +17,11 @@ "axios": "^0.24.0", "react": "^17.0.0", "react-dom": "^17.0.0", - "react-router-dom": "^6.0.2" + "react-router-dom": "^6.0.2", + "recoil": "^0.5.2" }, "devDependencies": { + "@tauri-apps/cli": "^1.0.0-beta.10", "@types/react": "^17.0.0", "@types/react-dom": "^17.0.0", "@vitejs/plugin-react": "^1.1.1", diff --git a/src/assets/styles/index.scss b/src/assets/styles/index.scss index 3d5ba11..7121814 100644 --- a/src/assets/styles/index.scss +++ b/src/assets/styles/index.scss @@ -1,7 +1,3 @@ -html { - background-color: #fefefe; -} - body { margin: 0; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", diff --git a/src/assets/styles/layout.scss b/src/assets/styles/layout.scss index 5f52266..1f17d8f 100644 --- a/src/assets/styles/layout.scss +++ b/src/assets/styles/layout.scss @@ -6,7 +6,14 @@ &__sidebar { position: relative; height: 100vh; - flex: 1 1 25%; + flex: 1 0 25%; + max-width: 250px; + } + + &__content { + flex: 1 1 75%; + padding: 20px 30px; + box-sizing: border-box; } &__traffic { @@ -19,10 +26,4 @@ margin: 0 auto; } } - - &__content { - flex: 1 1 75%; - padding: 20px 30px; - box-sizing: border-box; - } } diff --git a/src/components/list-item-link.tsx b/src/components/list-item-link.tsx index 95fc527..bc1bd31 100644 --- a/src/components/list-item-link.tsx +++ b/src/components/list-item-link.tsx @@ -12,16 +12,41 @@ const ListItemLink = (props: LinkProps) => { return ( { + if (!match) return {}; + + if (theme.palette.mode === "light") { + return { + bgcolor: "rgba(91,92,157,0.15)", + "&:hover": { bgcolor: "rgba(91,92,157,0.15)" }, + }; + } + + return { + bgcolor: "rgba(91,92,157,0.35)", + "&:hover": { bgcolor: "rgba(91,92,157,0.35)" }, + }; + }, + ]} onClick={() => navigate(to)} > { + if (!match) return "text.secondary"; + + const light = theme.palette.mode === "light"; + if (match && light) return "primary.main"; + return "primary.light"; + }, + }} /> diff --git a/src/components/palette-switch.tsx b/src/components/palette-switch.tsx new file mode 100644 index 0000000..49b37f7 --- /dev/null +++ b/src/components/palette-switch.tsx @@ -0,0 +1,51 @@ +import { styled, Switch } from "@mui/material"; + +// From: https://mui.com/components/switches/ +const PaletteSwitch = styled(Switch)(({ theme }) => ({ + width: 62, + height: 34, + padding: 7, + "& .MuiSwitch-switchBase": { + margin: 1, + padding: 0, + transform: "translateX(6px)", + "&.Mui-checked": { + color: "#fff", + transform: "translateX(22px)", + "& .MuiSwitch-thumb:before": { + backgroundImage: `url('data:image/svg+xml;utf8,')`, + }, + "& + .MuiSwitch-track": { + opacity: 1, + backgroundColor: theme.palette.mode === "dark" ? "#8796A5" : "#aab4be", + }, + }, + }, + "& .MuiSwitch-thumb": { + backgroundColor: theme.palette.mode === "dark" ? "#003892" : "#001e3c", + width: 32, + height: 32, + "&:before": { + content: "''", + position: "absolute", + width: "100%", + height: "100%", + left: 0, + top: 0, + backgroundRepeat: "no-repeat", + backgroundPosition: "center", + backgroundImage: `url('data:image/svg+xml;utf8,')`, + }, + }, + "& .MuiSwitch-track": { + opacity: 1, + backgroundColor: theme.palette.mode === "dark" ? "#8796A5" : "#aab4be", + borderRadius: 20 / 2, + }, +})); + +export default PaletteSwitch; diff --git a/src/main.tsx b/src/main.tsx index a9fa329..1e73217 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -2,32 +2,17 @@ import "./assets/styles/index.scss"; import React from "react"; import ReactDOM from "react-dom"; +import { RecoilRoot } from "recoil"; import { BrowserRouter } from "react-router-dom"; -import { createTheme, ThemeProvider } from "@mui/material"; import Layout from "./pages/_layout"; -const theme = createTheme({ - palette: { - mode: "light", - primary: { - main: "#5b5c9d", - }, - text: { - primary: "#637381", - secondary: "#909399", - }, - }, -}); - -// console.log(theme); - ReactDOM.render( - + - + , document.getElementById("root") ); diff --git a/src/pages/_layout.tsx b/src/pages/_layout.tsx index ee09077..0446538 100644 --- a/src/pages/_layout.tsx +++ b/src/pages/_layout.tsx @@ -1,5 +1,14 @@ +import { useMemo } from "react"; import { Route, Routes } from "react-router-dom"; -import { List, Paper, Typography } from "@mui/material"; +import { useRecoilValue } from "recoil"; +import { + createTheme, + List, + Paper, + ThemeProvider, + Typography, +} from "@mui/material"; +import { atomPaletteMode } from "../states/setting"; import LogPage from "../pages/log"; import HomePage from "../pages/home"; import ProxyPage from "../pages/proxy"; @@ -10,6 +19,8 @@ import ListItemLink from "../components/list-item-link"; import Traffic from "../components/traffic"; const Layout = () => { + const paletteMode = useRecoilValue(atomPaletteMode); + const routers = [ { label: "代理", @@ -33,41 +44,61 @@ const Layout = () => { }, ]; + const theme = useMemo(() => { + const bgcolor = paletteMode === "light" ? "#f5f5f5" : "#000"; + document.documentElement.style.background = bgcolor; + + return createTheme({ + palette: { + mode: paletteMode, + primary: { + main: "#5b5c9d", + }, + text: { + primary: "#637381", + secondary: "#909399", + }, + }, + }); + }, [paletteMode]); + return ( - -
- - Clash Verge - + + +
+ + Clash Verge + - - {routers.map((router) => ( - - {router.label} - - ))} - + + {routers.map((router) => ( + + {router.label} + + ))} + -
- +
+ +
-
-
- - } /> - } /> - } /> - } /> - } /> - } /> - -
-
+
+ + } /> + } /> + } /> + } /> + } /> + } /> + +
+ +
); }; diff --git a/src/pages/setting.tsx b/src/pages/setting.tsx index be8d857..f367828 100644 --- a/src/pages/setting.tsx +++ b/src/pages/setting.tsx @@ -1,5 +1,24 @@ +import { Box } from "@mui/system"; +import { useRecoilState } from "recoil"; +import { atomPaletteMode } from "../states/setting"; +import PaletteSwitch from "../components/palette-switch"; + const SettingPage = () => { - return

Setting

; + const [mode, setMode] = useRecoilState(atomPaletteMode); + + return ( + +

Setting

+ + + setMode(c ? "dark" : "light")} + inputProps={{ "aria-label": "controlled" }} + /> + +
+ ); }; export default SettingPage; diff --git a/src/states/setting.ts b/src/states/setting.ts new file mode 100644 index 0000000..56ceffd --- /dev/null +++ b/src/states/setting.ts @@ -0,0 +1,6 @@ +import { atom } from "recoil"; + +export const atomPaletteMode = atom<"light" | "dark">({ + key: "atomPaletteMode", + default: "light", +});