✨(demo) add theme selector
As we aims to create several themes for this demo app, we add a select to easily switch between all existing themes.
This commit is contained in:
committed by
Jean-Baptiste PENRATH
parent
be1e2e2614
commit
0ade12251e
@@ -1,13 +1,24 @@
|
||||
import { Button, CunninghamProvider } from "@openfun/cunningham-react";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { Button, CunninghamProvider, Select } from "@openfun/cunningham-react";
|
||||
import React, { useEffect, useMemo, useState } from "react";
|
||||
import { Create } from "./Create";
|
||||
import { Home } from "./Home";
|
||||
|
||||
enum Theme {
|
||||
DEFAULT = "default",
|
||||
CUNNINGHAM = "cunningham",
|
||||
}
|
||||
|
||||
enum Variant {
|
||||
LIGHT = "light",
|
||||
DARK = "dark",
|
||||
}
|
||||
|
||||
const THEMES: Record<Theme, Record<Variant, string | undefined>> = {
|
||||
[Theme.CUNNINGHAM]: {
|
||||
light: "default",
|
||||
dark: "dark",
|
||||
},
|
||||
};
|
||||
|
||||
export enum Page {
|
||||
HOME,
|
||||
CREATE,
|
||||
@@ -19,15 +30,27 @@ export interface PageProps {
|
||||
|
||||
const preferredScheme = window.matchMedia("(prefers-color-scheme: dark)")
|
||||
.matches
|
||||
? Theme.DARK
|
||||
: Theme.DEFAULT;
|
||||
? { theme: Theme.CUNNINGHAM, variant: Variant.DARK }
|
||||
: { theme: Theme.CUNNINGHAM, variant: Variant.LIGHT };
|
||||
|
||||
export const App = () => {
|
||||
const [locale] = useState("en-US");
|
||||
const [theme, setTheme] = useState<Theme>(preferredScheme);
|
||||
const [theme, setTheme] = useState<Theme>(
|
||||
(sessionStorage.getItem("c-theme") as Theme | null) ??
|
||||
preferredScheme.theme,
|
||||
);
|
||||
const [variant, setVariant] = useState<Variant>(
|
||||
(sessionStorage.getItem("c-variant") as Variant | null) ??
|
||||
preferredScheme.variant,
|
||||
);
|
||||
const activeTheme = useMemo(() => THEMES[theme][variant], [theme, variant]);
|
||||
const [page, setPage] = useState<Page>(Page.HOME);
|
||||
const handleThemeChange = (event: MediaQueryListEvent) =>
|
||||
setTheme(event.matches ? Theme.DARK : Theme.DEFAULT);
|
||||
const handleThemeChange = (event: MediaQueryListEvent) => {
|
||||
const nextVariant = event.matches ? Variant.DARK : Variant.LIGHT;
|
||||
if (THEMES[theme][nextVariant] !== undefined) {
|
||||
setVariant(nextVariant);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const query = window.matchMedia("(prefers-color-scheme: dark)");
|
||||
@@ -38,31 +61,66 @@ export const App = () => {
|
||||
};
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
document.documentElement.setAttribute("data-theme", theme);
|
||||
document.documentElement.setAttribute("data-variant", variant);
|
||||
sessionStorage.setItem("c-theme", theme);
|
||||
sessionStorage.setItem("c-variant", variant);
|
||||
}, [theme, variant]);
|
||||
|
||||
return (
|
||||
<CunninghamProvider currentLocale={locale} theme={theme}>
|
||||
<CunninghamProvider currentLocale={locale} theme={activeTheme}>
|
||||
<div className="container">
|
||||
<img
|
||||
className="pattern"
|
||||
src={
|
||||
theme === Theme.DARK ? "pattern_dark.png" : "pattern_default.png"
|
||||
}
|
||||
alt="Background pattern"
|
||||
/>
|
||||
{theme === Theme.CUNNINGHAM && (
|
||||
<img
|
||||
className="pattern"
|
||||
src={
|
||||
variant === Variant.DARK
|
||||
? "pattern_dark.png"
|
||||
: "pattern_default.png"
|
||||
}
|
||||
alt="Background pattern"
|
||||
/>
|
||||
)}
|
||||
{page === Page.HOME && <Home changePage={(p) => setPage(p)} />}
|
||||
{page === Page.CREATE && <Create changePage={(p) => setPage(p)} />}
|
||||
</div>
|
||||
|
||||
<div className="theme-switch">
|
||||
<Select
|
||||
value={theme}
|
||||
label="Theme"
|
||||
clearable={false}
|
||||
options={Object.keys(THEMES).map((key) => ({
|
||||
value: key,
|
||||
label: key[0].toUpperCase() + key.slice(1),
|
||||
}))}
|
||||
onChange={(e) => {
|
||||
setTheme(e.target.value as Theme);
|
||||
if (THEMES[e.target.value as Theme][variant] === undefined) {
|
||||
setVariant(
|
||||
variant === Variant.LIGHT ? Variant.DARK : Variant.LIGHT,
|
||||
);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
color="tertiary"
|
||||
icon={
|
||||
<span className="material-icons">
|
||||
{theme === Theme.DARK ? "light_mode" : "dark_mode"}
|
||||
{variant === Variant.DARK ? "light_mode" : "dark_mode"}
|
||||
</span>
|
||||
}
|
||||
onClick={() => {
|
||||
setTheme(theme === Theme.DARK ? Theme.DEFAULT : Theme.DARK);
|
||||
setVariant(
|
||||
variant === Variant.LIGHT ? Variant.DARK : Variant.LIGHT,
|
||||
);
|
||||
}}
|
||||
disabled={
|
||||
THEMES[theme][
|
||||
variant === Variant.LIGHT ? Variant.DARK : Variant.LIGHT
|
||||
] === undefined
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</CunninghamProvider>
|
||||
|
||||
@@ -35,6 +35,12 @@ html {
|
||||
position: fixed;
|
||||
right: 1rem;
|
||||
top: 0.75rem;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
|
||||
--c--components--forms-field--width: 150px;
|
||||
}
|
||||
|
||||
.card {
|
||||
|
||||
Reference in New Issue
Block a user