mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-24 02:02:36 -04:00
Add theme utils
This commit is contained in:
parent
cbbd04efb6
commit
000f7cbfe1
@ -38,18 +38,17 @@ import { Library, LibraryP, Page, Paged } from "~/models";
|
||||
import { QueryIdentifier, useFetch } from "~/utils/query";
|
||||
import { ErrorSnackbar } from "./errors";
|
||||
|
||||
const KyooTitle = (props: { sx: SxProps<Theme> }) => {
|
||||
const KyooTitle = () => {
|
||||
const { t } = useTranslation("common");
|
||||
|
||||
return (
|
||||
<Tooltip title={t("navbar.home")}>
|
||||
<ButtonLink
|
||||
sx={{
|
||||
css={{
|
||||
alignItems: "center",
|
||||
color: "inherit",
|
||||
textDecoration: "inherit",
|
||||
display: "flex",
|
||||
...props.sx,
|
||||
}}
|
||||
href="/"
|
||||
>
|
||||
@ -57,7 +56,7 @@ const KyooTitle = (props: { sx: SxProps<Theme> }) => {
|
||||
<Typography
|
||||
variant="h6"
|
||||
noWrap
|
||||
sx={{
|
||||
css={{
|
||||
ml: 1,
|
||||
mr: 2,
|
||||
fontFamily: "monospace",
|
||||
@ -90,7 +89,7 @@ export const Navbar = (barProps: AppBarProps) => {
|
||||
<MenuIcon />
|
||||
</IconButton>
|
||||
<Box sx={{ flexGrow: 1, display: { sx: "flex", sm: "none" } }} />
|
||||
<KyooTitle sx={{ mr: 1 }} />
|
||||
<KyooTitle css={{ mr: 1 }} />
|
||||
<Box sx={{ flexGrow: 1, display: { sx: "flex", sm: "none" } }} />
|
||||
<Box sx={{ flexGrow: 1, display: { xs: "none", sm: "flex" } }}>
|
||||
{isSuccess
|
||||
@ -110,7 +109,7 @@ export const Navbar = (barProps: AppBarProps) => {
|
||||
))}
|
||||
</Box>
|
||||
<Tooltip title={t("navbar.login")}>
|
||||
<IconButton sx={{ p: 0 }} href="/auth/login">
|
||||
<IconButton css={{ p: 0 }} href="/auth/login">
|
||||
<Avatar alt={t("navbar.login")} />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
|
67
front/src/components/primitives/text.tsx
Normal file
67
front/src/components/primitives/text.tsx
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Kyoo - A portable and vast media library solution.
|
||||
* Copyright (c) Kyoo.
|
||||
*
|
||||
* See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||
*
|
||||
* Kyoo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Kyoo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { forwardRef } from "react";
|
||||
|
||||
export const Heading = forwardRef<
|
||||
HTMLHeadingElement,
|
||||
{
|
||||
variant: "h1" | "h2" | "h3" | "h4" | "h5" | "h6";
|
||||
children?: JSX.Element | JSX.Element[];
|
||||
}
|
||||
>(function Heading({ variant = "h1", children, ...props }, ref) {
|
||||
const H = variant;
|
||||
return (
|
||||
<H
|
||||
ref={ref}
|
||||
{...props}
|
||||
css={(theme) => ({
|
||||
font: theme.fonts.heading,
|
||||
color: theme.heading,
|
||||
})}
|
||||
className={`Heading Heading-${variant}`}
|
||||
>
|
||||
{children}
|
||||
</H>
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
export const Paragraph = forwardRef<
|
||||
HTMLParagraphElement,
|
||||
{
|
||||
variant: "normal" | "subtext";
|
||||
children?: JSX.Element | JSX.Element[];
|
||||
}
|
||||
>(function Paragraph({ variant, children, ...props }, ref) {
|
||||
return (
|
||||
<p
|
||||
ref={ref}
|
||||
{...props}
|
||||
css={(theme) => ({
|
||||
font: theme.fonts.paragraph,
|
||||
color: variant === "normal" ? theme.paragraph : theme.subtext,
|
||||
})}
|
||||
className={`Paragraph Paragraph-${variant}`}
|
||||
>
|
||||
{children}
|
||||
</p>
|
||||
);
|
||||
});
|
@ -18,59 +18,83 @@
|
||||
* along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import React, { useState } from "react";
|
||||
import React, { ReactNode, useState } from "react";
|
||||
import appWithI18n from "next-translate/appWithI18n";
|
||||
import { ThemeProvider } from "@mui/material";
|
||||
import { ThemeProvider, useTheme } from "@emotion/react";
|
||||
import { createTheme, ThemeProvider as MTheme } from "@mui/material";
|
||||
import NextApp, { AppContext } from "next/app";
|
||||
import type { AppProps } from "next/app";
|
||||
import { Hydrate, QueryClientProvider } from "react-query";
|
||||
import { createQueryClient, fetchQuery, QueryIdentifier, QueryPage } from "~/utils/query";
|
||||
import { defaultTheme } from "~/utils/themes/default-theme";
|
||||
import superjson from "superjson";
|
||||
import Head from "next/head";
|
||||
import { useMobileHover } from "~/utils/utils";
|
||||
import { catppuccin } from "~/utils/themes/catppuccin";
|
||||
import { selectMode } from "~/utils/themes/theme";
|
||||
|
||||
// Simply silence a SSR warning (see https://github.com/facebook/react/issues/14927 for more details)
|
||||
if (typeof window === "undefined") {
|
||||
React.useLayoutEffect = React.useEffect;
|
||||
}
|
||||
|
||||
const ThemeSelector = ({ children }: { children?: ReactNode | ReactNode[] }) => {
|
||||
// TODO: Handle user selected mode (light, dark, auto)
|
||||
// TODO: Hande theme change.
|
||||
return (
|
||||
<MTheme theme={createTheme()}>
|
||||
<ThemeProvider theme={selectMode(catppuccin, "light")}>
|
||||
{children}
|
||||
</ThemeProvider>
|
||||
</MTheme>
|
||||
)
|
||||
}
|
||||
|
||||
const GlobalCssTheme = () => {
|
||||
const theme = useTheme();
|
||||
|
||||
return (
|
||||
<style jsx global>{`
|
||||
body {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
background-color: ${theme.background};
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar {
|
||||
height: 6px;
|
||||
width: 6px;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar-thumb {
|
||||
background-color: #999;
|
||||
border-radius: 90px;
|
||||
}
|
||||
*:hover::-webkit-scrollbar-thumb {
|
||||
background-color: rgb(134, 127, 127);
|
||||
}
|
||||
`}</style>
|
||||
);
|
||||
};
|
||||
|
||||
const App = ({ Component, pageProps }: AppProps) => {
|
||||
const [queryClient] = useState(() => createQueryClient());
|
||||
const { queryState, ...props } = superjson.deserialize<any>(pageProps ?? {});
|
||||
const { queryState, ...props } = superjson.deserialize<any>(pageProps ?? { json: {} });
|
||||
const getLayout = (Component as QueryPage).getLayout ?? ((page) => page);
|
||||
|
||||
useMobileHover();
|
||||
|
||||
return (
|
||||
<>
|
||||
<style jsx global>{`
|
||||
body {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
background-color: ${defaultTheme.palette.background.default};
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar {
|
||||
height: 6px;
|
||||
width: 6px;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
*::-webkit-scrollbar-thumb {
|
||||
background-color: #999;
|
||||
border-radius: 90px;
|
||||
}
|
||||
*:hover::-webkit-scrollbar-thumb {
|
||||
background-color: rgb(134, 127, 127);
|
||||
}
|
||||
`}</style>
|
||||
<Head>
|
||||
<title>Kyoo</title>
|
||||
</Head>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<Hydrate state={queryState}>
|
||||
<ThemeProvider theme={defaultTheme}>{getLayout(<Component {...props} />)}</ThemeProvider>
|
||||
<ThemeSelector>
|
||||
<GlobalCssTheme />
|
||||
{getLayout(<Component {...props} />)}
|
||||
</ThemeSelector>
|
||||
</Hydrate>
|
||||
</QueryClientProvider>
|
||||
</>
|
||||
|
@ -18,36 +18,17 @@
|
||||
* along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { Property } from "csstype";
|
||||
import { ThemeBuilder } from "./theme";
|
||||
|
||||
// TODO: Add specifics colors
|
||||
export type Theme = {
|
||||
fonts: {
|
||||
heading: string,
|
||||
paragraph: string,
|
||||
},
|
||||
light: {
|
||||
appbar: Property.Color,
|
||||
default: {
|
||||
background: Property.Color,
|
||||
accent: Property.Color,
|
||||
divider: Property.Color,
|
||||
heading: Property.Color,
|
||||
paragraph: Property.Color,
|
||||
subtext: Property.Color,
|
||||
},
|
||||
variant: Theme["light"]["default"],
|
||||
},
|
||||
dark: Theme["light"]
|
||||
}
|
||||
|
||||
export const catppuccin: Theme = {
|
||||
export const catppuccin: ThemeBuilder = {
|
||||
fonts: {
|
||||
heading: "Pacifico",
|
||||
paragraph: "Poppins",
|
||||
},
|
||||
light: {
|
||||
appbar: "#e64553",
|
||||
contrast: "#cdd6f4",
|
||||
subcontrast: "#bac2de",
|
||||
default: {
|
||||
background: "#eff1f5",
|
||||
accent: "#ea76cb",
|
||||
@ -63,10 +44,12 @@ export const catppuccin: Theme = {
|
||||
heading: "#4c4f69",
|
||||
paragraph: "#5c5f77",
|
||||
subtext: "#6c6f85",
|
||||
}
|
||||
},
|
||||
},
|
||||
dark: {
|
||||
appbar: "#94e2d5",
|
||||
contrast: "#cdd6f4",
|
||||
subcontrast: "#bac2de",
|
||||
default: {
|
||||
background: "#1e1e2e",
|
||||
accent: "##f5c2e7",
|
||||
@ -83,5 +66,5 @@ export const catppuccin: Theme = {
|
||||
paragraph: "#bac2de",
|
||||
subtext: "#a6adc8",
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
86
front/src/utils/themes/theme.tsx
Normal file
86
front/src/utils/themes/theme.tsx
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Kyoo - A portable and vast media library solution.
|
||||
* Copyright (c) Kyoo.
|
||||
*
|
||||
* See AUTHORS.md and LICENSE file in the project root for full license information.
|
||||
*
|
||||
* Kyoo is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* any later version.
|
||||
*
|
||||
* Kyoo is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { Property } from "csstype";
|
||||
import "@emotion/react";
|
||||
import { Theme, ThemeProvider, useTheme } from "@emotion/react";
|
||||
|
||||
type ThemeSettings = {
|
||||
fonts: {
|
||||
heading: string;
|
||||
paragraph: string;
|
||||
};
|
||||
};
|
||||
|
||||
type Mode = Variant & {
|
||||
appbar: Property.Color;
|
||||
/*
|
||||
* The color used in texts or button that are hover black shades on images (ShowHeader, player...)
|
||||
*/
|
||||
contrast: Property.Color;
|
||||
subcontrast: Property.Color;
|
||||
variant: Variant;
|
||||
};
|
||||
|
||||
type Variant = {
|
||||
background: Property.Color;
|
||||
accent: Property.Color;
|
||||
divider: Property.Color;
|
||||
heading: Property.Color;
|
||||
paragraph: Property.Color;
|
||||
subtext: Property.Color;
|
||||
};
|
||||
|
||||
declare module "@emotion/react" {
|
||||
// TODO: Add specifics colors
|
||||
export interface Theme extends ThemeSettings, Mode {}
|
||||
}
|
||||
|
||||
export type { Theme } from "@emotion/react";
|
||||
export type ThemeBuilder = ThemeSettings & {
|
||||
light: Mode;
|
||||
dark: Mode;
|
||||
};
|
||||
|
||||
export const selectMode = (theme: ThemeBuilder, mode: "light" | "dark"): Theme => {
|
||||
const value = (mode === "light" ? theme.light : theme.dark);
|
||||
return { fonts: theme.fonts, ...(value.default), variant: value.variant };
|
||||
};
|
||||
|
||||
export const switchVariant = (theme: Theme) => {
|
||||
return {
|
||||
...theme,
|
||||
...theme.variant,
|
||||
variant: {
|
||||
background: theme.background,
|
||||
accent: theme.accent,
|
||||
divider: theme.divider,
|
||||
heading: theme.heading,
|
||||
paragraph: theme.paragraph,
|
||||
subtext: theme.subtext,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
export const SwitchVariant = ({ children }: { children?: JSX.Element | JSX.Element[] }) => {
|
||||
const theme = useTheme();
|
||||
|
||||
return <ThemeProvider theme={switchVariant(theme)}>{children}</ThemeProvider>;
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user