feat: dark mode support for auth page (#569)

* feat: dark mode support for auth page

* chore: update
This commit is contained in:
Stephen Zhou 2022-11-26 11:20:22 +08:00 committed by GitHub
parent 2d5d734da4
commit 90c85103c3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 111 additions and 8 deletions

View file

@ -0,0 +1,53 @@
import { Option, Select } from "@mui/joy";
import { useTranslation } from "react-i18next";
import Icon from "./Icon";
import { APPERANCE_OPTIONS } from "../helpers/consts";
import useApperance, { Apperance } from "../hooks/useApperance";
const ApperanceDropdownMenu = () => {
const [apperance, setApperance] = useApperance();
const { t } = useTranslation();
const apperanceOptionItems = [
[
APPERANCE_OPTIONS[0],
<>
<Icon.Feather className="w-4 h-4" />
<p>{t("setting.apperance-option.follow-system")}</p>
</>,
],
[
APPERANCE_OPTIONS[1],
<>
<Icon.Sun className="w-4 h-4" />
<p>{t("setting.apperance-option.always-light")}</p>
</>,
],
[
APPERANCE_OPTIONS[2],
<>
<Icon.Moon className="w-4 h-4" />
<p>{t("setting.apperance-option.always-dark")}</p>
</>,
],
] as const;
return (
<Select
className="w-56 text-sm"
value={apperance}
onChange={(_, value) => {
setApperance(value as Apperance);
}}
>
{apperanceOptionItems.map((item) => (
<Option key={item[0]} value={item[0]}>
<span className="flex items-center gap-2">{item[1]}</span>
</Option>
))}
</Select>
);
};
export default ApperanceDropdownMenu;

View file

@ -22,3 +22,6 @@ export const IS_FOLDING_ENABLED_DEFAULT_VALUE = true;
export const SETTING_IS_FOLDING_ENABLED_KEY = "setting_IS_FOLDING_ENABLED";
export const TAB_SPACE_WIDTH = 2;
export const APPERANCE_OPTIONS = ["auto", "light", "dark"] as const;
export const APPERANCE_OPTIONS_STORAGE_KEY = "setting_APPERANCE_OPTIONS";

View file

@ -0,0 +1,28 @@
import { useEffect } from "react";
import { useColorScheme } from "@mui/joy/styles";
import { APPERANCE_OPTIONS, APPERANCE_OPTIONS_STORAGE_KEY } from "../helpers/consts";
import useLocalStorage from "./useLocalStorage";
export type Apperance = typeof APPERANCE_OPTIONS[number];
const useApperance = () => {
const [apperance, setApperance] = useLocalStorage<Apperance>(APPERANCE_OPTIONS_STORAGE_KEY, APPERANCE_OPTIONS[0]);
const { setMode } = useColorScheme();
useEffect(() => {
const root = document.documentElement;
if (apperance === "dark" || (apperance === "auto" && window.matchMedia("(prefers-color-scheme: dark)").matches)) {
root.classList.add("dark");
setMode("dark");
} else {
root.classList.remove("dark");
setMode("light");
}
}, [apperance]);
return [apperance, setApperance] as const;
};
export default useApperance;

View file

@ -1,5 +1,5 @@
.page-wrapper.auth {
@apply flex flex-row justify-center items-center w-full h-screen bg-white;
@apply flex flex-row justify-center items-center w-full h-screen bg-white dark:bg-zinc-900;
> .page-container {
@apply w-80 max-w-full h-full py-4 flex flex-col justify-start items-center;
@ -11,15 +11,19 @@
@apply flex flex-col justify-start items-start w-full mb-4;
> .title-container {
@apply w-full flex flex-row justify-between items-center;
@apply w-full flex flex-row justify-start items-center;
> .logo-img {
@apply h-20 w-auto;
}
> .logo-text {
@apply text-4xl tracking-wide text-black dark:text-white;
}
}
> .slogan-text {
@apply text-sm text-gray-700;
@apply text-sm text-gray-700 dark:text-gray-200;
}
}
@ -33,7 +37,7 @@
@apply absolute top-3 left-3 px-1 leading-10 flex-shrink-0 text-base cursor-text text-gray-400 bg-transparent transition-all select-none;
&.not-null {
@apply text-sm top-0 z-10 leading-4 bg-white rounded;
@apply text-sm top-0 z-10 leading-4 bg-white dark:bg-zinc-800 rounded;
}
}
@ -41,7 +45,7 @@
@apply py-2;
> input {
@apply w-full py-3 px-3 text-base shadow-inner rounded-lg border border-solid border-gray-400 hover:opacity-80;
@apply w-full py-3 px-3 text-base shadow-inner rounded-lg border border-solid border-gray-400 hover:opacity-80 dark:bg-zinc-800 dark:text-white;
}
}
}
@ -58,7 +62,7 @@
@apply flex flex-row justify-center items-center px-1 py-2 text-sm rounded hover:opacity-80;
&.signup-btn {
@apply px-3;
@apply px-3 dark:text-white dark:opacity-70;
}
&.signin-btn {

View file

@ -160,6 +160,11 @@
"additional-script": "Additional script",
"additional-style-placeholder": "Additional CSS codes",
"additional-script-placeholder": "Additional JavaScript codes"
},
"apperance-option": {
"follow-system": "Follow system",
"always-light": "Always light",
"always-dark": "Always dark"
}
},
"amount-text": {

View file

@ -160,6 +160,11 @@
"additional-script": "自定义脚本",
"additional-style-placeholder": "自定义 CSS 代码",
"additional-script-placeholder": "自定义 JavaScript 代码"
},
"apperance-option": {
"follow-system": "跟随系统",
"always-light": "总是浅色",
"always-dark": "总是深色"
}
},
"amount-text": {

View file

@ -9,6 +9,7 @@ import useLoading from "../hooks/useLoading";
import { globalService, userService } from "../services";
import Icon from "../components/Icon";
import toastHelper from "../components/Toast";
import ApperanceDropdownMenu from "../components/ApperanceDropdownMenu";
import "../less/auth.less";
const validateConfig: ValidatorConfig = {
@ -113,7 +114,8 @@ const Auth = () => {
<div className="auth-form-wrapper">
<div className="page-header-container">
<div className="title-container">
<img className="logo-img" src="/logo-full.webp" alt="" />
<img className="logo-img" src="/logo.webp" alt="" />
<p className="logo-text">memos</p>
</div>
<p className="slogan-text">{t("slogan")}</p>
</div>
@ -160,7 +162,7 @@ const Auth = () => {
{!systemStatus?.host && <p className="tip-text">{t("auth.host-tip")}</p>}
</div>
<div className="footer-container">
<div className="w-full flex flex-row justify-center items-center">
<div className="w-full flex flex-row justify-center items-center gap-2">
<Select
className="w-40 text-sm"
startDecorator={<Icon.Globe className="w-4 h-auto" />}
@ -172,6 +174,7 @@ const Auth = () => {
<Option value="vi">Tiếng Việt</Option>
<Option value="fr">French</Option>
</Select>
<ApperanceDropdownMenu />
</div>
</div>
</div>

View file

@ -1,6 +1,8 @@
/* eslint-disable no-undef */
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ["./index.html", "./src/**/*.{js,ts,tsx}"],
darkMode: "class",
theme: {
fontSize: {
xs: ".75rem",