108 lines
2.9 KiB
TypeScript
108 lines
2.9 KiB
TypeScript
import React, { useState, useMemo, createContext, useContext } from "react";
|
|
|
|
import { createTheme, ThemeProvider } from "@mui/material/styles";
|
|
import useMediaQuery from "@mui/material/useMediaQuery";
|
|
import blueGrey from "@mui/material/colors/blueGrey"
|
|
import teal from "@mui/material/colors/teal";
|
|
|
|
import AppBar from "@mui/material/AppBar";
|
|
import Box from "@mui/material/Box";
|
|
import Button from "@mui/material/Button";
|
|
import Brightness4Icon from "@mui/icons-material/Brightness4";
|
|
import Container from "@mui/material/Container";
|
|
import CssBaseline from "@mui/material/CssBaseline";
|
|
import IconButton from "@mui/material/IconButton";
|
|
import Menu from "@mui/material/Menu";
|
|
import MenuItem from "@mui/material/MenuItem";
|
|
import Toolbar from "@mui/material/Toolbar";
|
|
import Typography from "@mui/material/Typography";
|
|
import Sliders from "./Sliders";
|
|
|
|
// Light / Dark mode
|
|
|
|
type ThemeMode = 'system' | 'light' | 'dark';
|
|
const ThemeModeContext = createContext((_: ThemeMode) => { })
|
|
|
|
const App: React.FC = () => {
|
|
|
|
const systemDarkMode = useMediaQuery('(prefers-color-scheme: dark)');
|
|
|
|
const [themeMode, setThemeMode] = useState<ThemeMode>('system');
|
|
|
|
const theme = useMemo(
|
|
() => createTheme({
|
|
palette: {
|
|
mode: themeMode === 'system' ? (systemDarkMode ? 'dark' : 'light') : themeMode,
|
|
primary: blueGrey,
|
|
secondary: teal,
|
|
}
|
|
}),
|
|
[themeMode, systemDarkMode],
|
|
);
|
|
|
|
return <ThemeModeContext.Provider value={setThemeMode}>
|
|
<ThemeProvider theme={theme}>
|
|
<CssBaseline />
|
|
<Layout />
|
|
</ThemeProvider>
|
|
</ThemeModeContext.Provider>
|
|
}
|
|
|
|
// Layout
|
|
|
|
const Layout: React.FC = () => {
|
|
return <>
|
|
<TopBar />
|
|
<main>
|
|
<Box sx={{
|
|
pt: 8,
|
|
pb: 6,
|
|
}}>
|
|
<Container>
|
|
<Sliders />
|
|
</Container>
|
|
</Box>
|
|
</main>
|
|
</>
|
|
}
|
|
|
|
// Top Bar
|
|
|
|
const TopBar: React.FC = () => {
|
|
|
|
const setThemeMode = useContext(ThemeModeContext);
|
|
const [anchorEl, setAnchorEl] = useState<HTMLButtonElement | null>(null);
|
|
const open = Boolean(anchorEl);
|
|
|
|
return <AppBar position="relative">
|
|
<Toolbar>
|
|
<Typography variant="h6" sx={{ flexGrow: 1 }}>
|
|
DMX Controllinator
|
|
</Typography>
|
|
<IconButton
|
|
onClick={(event: React.MouseEvent<HTMLButtonElement>) => { setAnchorEl(event.currentTarget) }}
|
|
color="inherit"
|
|
>
|
|
<Brightness4Icon />
|
|
</IconButton>
|
|
<Menu
|
|
open={open}
|
|
anchorEl={anchorEl}
|
|
onClose={() => { setAnchorEl(null) }}
|
|
>
|
|
<MenuItem onClick={() => { setAnchorEl(null); setThemeMode('light'); }}>Light</MenuItem>
|
|
<MenuItem onClick={() => { setAnchorEl(null); setThemeMode('system'); }}>System</MenuItem>
|
|
<MenuItem onClick={() => { setAnchorEl(null); setThemeMode('dark'); }}>Dark</MenuItem>
|
|
</Menu>
|
|
<Button variant="contained" href="docs">
|
|
API
|
|
</Button>
|
|
</Toolbar>
|
|
</AppBar >
|
|
}
|
|
|
|
// Content
|
|
|
|
|
|
export default App;
|