mirror of
https://github.com/webstudio-is/webstudio.git
synced 2026-11-09 22:14:29 +09:00
better semantics
This commit is contained in:
1 parent
856a13a6d6
commit
57fd8548ab
5 files changed
+32
-32
No files matched your search
@@ -20,7 +20,7 @@ import {
|
||||
useIsPublishDialogOpen,
|
||||
} from "~/designer/shared/nano-states";
|
||||
import { isFeatureEnabled } from "~/shared/feature-flags";
|
||||
import { getThemeOption, setThemeOption } from "~/shared/theme";
|
||||
import { getThemeSetting, setThemeSetting } from "~/shared/theme";
|
||||
|
||||
const menuItemCss = {
|
||||
display: "flex",
|
||||
@@ -37,7 +37,7 @@ const textCss = {
|
||||
|
||||
const ThemeMenuItem = () => {
|
||||
if (isFeatureEnabled("theme") === false) return null;
|
||||
const currentOption = getThemeOption();
|
||||
const currentOption = getThemeSetting();
|
||||
const labels = {
|
||||
light: "Light",
|
||||
dark: "Dark",
|
||||
@@ -59,7 +59,7 @@ const ThemeMenuItem = () => {
|
||||
checked={currentOption === option}
|
||||
css={menuItemCss}
|
||||
onSelect={() => {
|
||||
setThemeOption(option);
|
||||
setThemeSetting(option);
|
||||
}}
|
||||
>
|
||||
<Text css={textCss}>{labels[option]}</Text>
|
||||
|
||||
+3
-3
@@ -2,9 +2,9 @@ import { json, type LoaderFunction } from "@remix-run/node";
|
||||
import { themeCookieParser } from "~/shared/theme/index.server";
|
||||
|
||||
export const loader: LoaderFunction = async ({ params }) => {
|
||||
const { option } = params;
|
||||
const { setting } = params;
|
||||
const headers = {
|
||||
"Set-Cookie": await themeCookieParser.serialize(option),
|
||||
"Set-Cookie": await themeCookieParser.serialize(setting),
|
||||
};
|
||||
return json({ option }, { headers });
|
||||
return json({ setting }, { headers });
|
||||
};
|
||||
@@ -1,5 +1,5 @@
|
||||
export type ThemeName = "dark" | "light";
|
||||
export type ColorScheme = "dark" | "light";
|
||||
|
||||
export type ThemeOption = ThemeName | "system";
|
||||
export type ThemeSetting = ColorScheme | "system";
|
||||
|
||||
export const cookieNamespace = "theme";
|
||||
@@ -1,14 +1,14 @@
|
||||
import { createCookie } from "@remix-run/node";
|
||||
import { cookieNamespace, type ThemeName, type ThemeOption } from "./shared";
|
||||
import { cookieNamespace, type ColorScheme, type ThemeSetting } from "./shared";
|
||||
|
||||
export const themeCookieParser = createCookie(cookieNamespace);
|
||||
|
||||
export const getServerTheme = async (
|
||||
request: Request
|
||||
): Promise<{ system?: ThemeName; option?: ThemeOption }> => {
|
||||
): Promise<{ system?: ColorScheme; option?: ThemeSetting }> => {
|
||||
const system = (request.headers.get("Sec-CH-Prefers-Color-Scheme") ??
|
||||
undefined) as ThemeName | undefined;
|
||||
const option: ThemeOption =
|
||||
undefined) as ColorScheme | undefined;
|
||||
const option: ThemeSetting =
|
||||
(await themeCookieParser.parse(request.headers.get("Cookie"))) ?? undefined;
|
||||
return { system, option };
|
||||
};
|
||||
@@ -1,30 +1,30 @@
|
||||
import { useLoaderData } from "@remix-run/react";
|
||||
import { darkTheme } from "~/shared/design-system";
|
||||
import { type ThemeName, type ThemeOption } from "./shared";
|
||||
import { type ColorScheme, type ThemeSetting } from "./shared";
|
||||
|
||||
// User selected theme option.
|
||||
let option: ThemeOption = "dark";
|
||||
// User selected theme setting.
|
||||
let setting: ThemeSetting = "dark";
|
||||
// Current systeme theme.
|
||||
let system: ThemeName;
|
||||
let system: ColorScheme;
|
||||
|
||||
const subscribeSystemTheme = () => {
|
||||
if (typeof matchMedia === "undefined") return;
|
||||
const query = matchMedia("(prefers-color-scheme: light)");
|
||||
const getTheme = (query: MediaQueryList | MediaQueryListEvent) =>
|
||||
const getColorScheme = (query: MediaQueryList | MediaQueryListEvent) =>
|
||||
query.matches ? "light" : "dark";
|
||||
|
||||
system = getTheme(query);
|
||||
system = getColorScheme(query);
|
||||
|
||||
query.addEventListener("change", (queryEvent) => {
|
||||
system = getTheme(queryEvent);
|
||||
system = getColorScheme(queryEvent);
|
||||
setDomProps();
|
||||
});
|
||||
};
|
||||
|
||||
subscribeSystemTheme();
|
||||
|
||||
export const getThemeOption = (): ThemeOption => {
|
||||
return option;
|
||||
export const getThemeSetting = (): ThemeSetting => {
|
||||
return setting;
|
||||
};
|
||||
|
||||
// @todo todo switch to light by default once ready
|
||||
@@ -32,19 +32,19 @@ export const defaultTheme = "dark";
|
||||
|
||||
const selectTheme = ({
|
||||
system = defaultTheme,
|
||||
option,
|
||||
setting,
|
||||
}: {
|
||||
system: ThemeName;
|
||||
option?: ThemeOption;
|
||||
}): ThemeName => {
|
||||
if (option === "system") {
|
||||
system: ColorScheme;
|
||||
setting?: ThemeSetting;
|
||||
}): ColorScheme => {
|
||||
if (setting === "system") {
|
||||
return system;
|
||||
}
|
||||
return option || defaultTheme;
|
||||
return setting || defaultTheme;
|
||||
};
|
||||
|
||||
const getThemeProps = () => {
|
||||
const theme = selectTheme({ option, system });
|
||||
const theme = selectTheme({ setting, system });
|
||||
if (theme === "dark") {
|
||||
// We need to call it so that vars get injected!!!
|
||||
darkTheme.toString();
|
||||
@@ -61,15 +61,15 @@ const setDomProps = () => {
|
||||
document.documentElement.style.colorScheme = props.style.colorScheme;
|
||||
};
|
||||
|
||||
export const setThemeOption = (nextOption: ThemeOption) => {
|
||||
option = nextOption;
|
||||
export const setThemeSetting = (nextsetting: ThemeSetting) => {
|
||||
setting = nextsetting;
|
||||
setDomProps();
|
||||
fetch(`/rest/theme/${option}`);
|
||||
fetch(`/rest/theme/${setting}`);
|
||||
};
|
||||
|
||||
export const useThemeProps = () => {
|
||||
const data = useLoaderData();
|
||||
if (data.theme.option) option = data.theme.option;
|
||||
if (data.theme.setting) setting = data.theme.setting;
|
||||
if (data.theme.system) system = data.theme.system;
|
||||
return getThemeProps();
|
||||
};
|
||||
Reference in new issue
Block a user