Skip to content

Commit

Permalink
Theme customization and typing. Some values used in both MUI theme an…
Browse files Browse the repository at this point in the history
…d custom css.
  • Loading branch information
Luis Doebbel committed Sep 23, 2024
1 parent 9d178cb commit 04e4554
Show file tree
Hide file tree
Showing 13 changed files with 245 additions and 76 deletions.
28 changes: 23 additions & 5 deletions frontend/src/app/components/errorHelperText/ErrorHelperText.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,30 @@
import Typography from "@mui/material/Typography";
import { RefObject, useEffect, useRef, useState } from "react";
import { CSSTransition, TransitionGroup } from "react-transition-group";
import classes from "./error-helper-text.module.css";
import { css } from "@mui/material-pigment-css";

interface IErrorBox {
message: string;
}

const enter = css`
opacity: 0;
`;

const enterActive = css(({ theme }) => ({
opacity: 1,
transition: `opacity ${theme.transitions.duration.short}ms ${theme.transitions.easing.easeIn}`,
}));

const exit = css`
opacity: 0;
`;

const exitActive = css(({ theme }) => ({
opacity: 0,
transition: `opacity ${theme.transitions.duration.short}ms ${theme.transitions.easing.easeOut}`,
}));

export default function ErrorHelperText({ message }: IErrorBox) {
const [activeMessage, setActiveMessage] = useState<string | undefined>(
undefined,
Expand All @@ -21,10 +39,10 @@ export default function ErrorHelperText({ message }: IErrorBox) {
{activeMessage && (
<CSSTransition
classNames={{
enter: classes["enter"],
enterActive: classes["enter-active"],
exit: classes["exit"],
exitActive: classes["exit-active"],
enter: enter,
enterActive: enterActive,
exit: exit,
exitActive: exitActive,
}}
timeout={350}
nodeRef={nodeRef}
Expand Down
15 changes: 13 additions & 2 deletions frontend/src/app/components/loading/Loading.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@ import Spinner from "@components/spinner/Spinner";
import { RefObject, useRef } from "react";
import { CSSTransition, TransitionGroup } from "react-transition-group";
import classes from "./loading.module.css";
import { css } from "@mui/material-pigment-css";

const enterActive = css(({ theme }) => ({
opacity: 1,
transition: `opacity ${theme.transitions.duration.standard}ms ${theme.transitions.easing.easeIn}`,
}));

const exitActive = css(({ theme }) => ({
opacity: 0,
transition: `opacity ${theme.transitions.duration.standard}ms ${theme.transitions.easing.easeOut}`,
}));

interface ILoading {
isLoading?: boolean;
Expand All @@ -16,9 +27,9 @@ export default function Loading({ isLoading = true }: ILoading) {
<CSSTransition
classNames={{
enter: classes["enter"],
enterActive: classes["enter-active"],
enterActive: enterActive,
exit: classes["exit"],
exitActive: classes["exit-active"],
exitActive: exitActive,
}}
timeout={500}
nodeRef={nodeRef}
Expand Down
10 changes: 0 additions & 10 deletions frontend/src/app/components/loading/loading.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,6 @@
opacity: 0;
}

.enter-active {
opacity: 1;
transition: opacity 0.5s ease-in;
}

.exit {
opacity: 1;
}

.enter-active {
opacity: 0;
transition: opacity 0.5s ease-out;
}
2 changes: 1 addition & 1 deletion frontend/src/app/components/spinner/Spinner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export default function Spinner() {
return (
<span
sx={(theme) => ({
backgroundImage: `linear-gradient(${theme.palette.primary.main} 16px,transparent 0),
backgroundImage: `linear-gradient(${theme.palette.primary.dark} 16px,transparent 0),
linear-gradient(${theme.palette.primary.main} 16px, transparent 0),
linear-gradient(${theme.palette.primary.main} 16px, transparent 0),
linear-gradient(${theme.palette.primary.dark} 16px, transparent 0)`,
Expand Down
52 changes: 32 additions & 20 deletions frontend/src/material-ui-pigment-css.d.ts
Original file line number Diff line number Diff line change
@@ -1,53 +1,65 @@
import { Theme, SxProps } from "@mui/material/styles";
import {} from "@mui/material/themeCssVarsAugmentation";

// Extend the Pigment CSS theme types with Material UI Theme
declare module "@mui/material-pigment-css" {
interface ThemeArgs {
theme: Theme;
}
}

declare module "@mui/material/styles" {
// Named like this to augment the existing ZIndex theme type
interface ZIndex {
debugBanner: number;
cookieBanner: number;
loading: number;
}

interface CustomSpacing {
a: string;
xxs: string;
xs: string;
sm: string;
md: string;
lg: string;
xl: string;
xxl: string;
}

interface CustomBorderRadius {
xs: string;
sm: string;
md: string;
lg: string;
}

interface CustomTime {
normal: string;
slow: string;
}

interface Theme {
zIndex: ZIndex;
customProperties: {
borderRadius: {
xs: string;
sm: string;
md: string;
lg: string;
};
time: {
normal: string;
slow: string;
};
spacing: CustomSpacing;
borderRadius: CustomBorderRadius;
time: Partial<CustomTime>;
};
}

// allow configuration using `createTheme`
interface ThemeOptions {
zIndex?: Partial<ZIndex>;
customProperties?: {
borderRadius?: {
xs: string;
sm: string;
md: string;
lg: string;
};
time?: {
normal: string;
slow: string;
};
spacing?: Partial<CustomSpacing>;
borderRadius?: Partial<CustomBorderRadius>;
time?: Partial<CustomTime>;
};
}
}

// Allows typescript to recognize sx prop on HTML elements
declare global {
namespace React {
interface HTMLAttributes {
Expand Down
39 changes: 39 additions & 0 deletions frontend/src/styles/_fonts.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
@font-face {
font-family: InterTight;
font-style: normal;
font-weight: 400;
font-display: swap;
src:
url("@assets/fonts/InterTight/InterTight-Regular.woff2") format("woff2"),
url("@assets/fonts/InterTight/InterTight-Regular.ttf") format("truetype");
}

@font-face {
font-family: InterTight;
font-style: normal;
font-weight: 500;
font-display: swap;
src:
url("@assets/fonts/InterTight/InterTight-Medium.woff2") format("woff2"),
url("@assets/fonts/InterTight/InterTight-Medium.ttf") format("truetype");
}

@font-face {
font-family: InterTight;
font-style: normal;
font-weight: 600;
font-display: swap;
src:
url("@assets/fonts/InterTight/InterTight-SemiBold.woff2") format("woff2"),
url("@assets/fonts/InterTight/InterTight-SemiBold.ttf") format("truetype");
}

@font-face {
font-family: InterTight;
font-style: normal;
font-weight: 700;
font-display: swap;
src:
url("@assets/fonts/InterTight/InterTight-Bold.woff2") format("woff2"),
url("@assets/fonts/InterTight/InterTight-Bold.ttf") format("truetype");
}
4 changes: 1 addition & 3 deletions frontend/src/styles/_globals.scss
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ body {
flex-direction: column;
min-height: 100%;
width: 100%;
font-family: InterTight, sans-serif;
font-size: 16px;
overflow-y: scroll;
}

Expand All @@ -23,7 +21,7 @@ body {
flex: 1 1 auto;
height: 100%;
width: 100%;
animation: 0.5s fade-in forwards;
animation: var(--mui-customProperties-time-slow) fade-in forwards;
}

.flex {
Expand Down
19 changes: 9 additions & 10 deletions frontend/src/styles/_variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,16 @@
= Variables =
============================================ */

// ideally, these should match the spacing from MUI
// Allow utility classes to use the same spacing properties defined in the MUI theme
$spacing: (
0: 0,
a: auto,
xxs: 0.25rem,
xs: 0.5rem,
sm: 0.75rem,
md: 1rem,
lg: 1.5rem,
xl: 2rem,
xxl: 3rem,
a: var(--mui-customProperties-spacing-a),
xxs: var(--mui-customProperties-spacing-xxs),
xs: var(--mui-customProperties-spacing-xs),
sm: var(--mui-customProperties-spacing-sm),
md: var(--mui-customProperties-spacing-md),
lg: var(--mui-customProperties-spacing-lg),
xl: var(--mui-customProperties-spacing-xl),
xxl: var(--mui-customProperties-spacing-xxl),
);

$direction: (
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/styles/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@

@forward "export";

@forward "fonts";

@forward "globals";
4 changes: 2 additions & 2 deletions frontend/src/themes/palette.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ export default function getPalette(): PaletteOptions {
light: blue[300],
400: blue[400],
main: blue[500],
dark: blue[600],
600: blue[600],
700: blue[700],
900: blue[900],
dark: blue[900],
contrastText,
},
secondary: {
Expand Down
46 changes: 23 additions & 23 deletions frontend/src/themes/theme.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,34 @@
import { createTheme } from "@mui/material/styles";
import palette from "./palette";
import typography from "./typography";
import {
breakpoints,
zIndex,
spacingValues,
borderRadius,
time,
} from "./variables";

const theme = createTheme({
cssVariables: true,
cssVariables: true, // creates css variables for theme values
breakpoints: {
values: {
xs: 640,
sm: 768,
md: 1024,
lg: 1280,
xl: 1440,
},
},
zIndex: {
debugBanner: 100,
cookieBanner: 200,
loading: 1000,
values: breakpoints,
},
zIndex: zIndex,
palette: palette(),
typography,
spacing: (value: number | keyof typeof spacingValues) => {
if (typeof value === "number") {
return `${0.25 * value}rem`;
}
return spacingValues[value];
},
// custom properties will also be available as css variables
// for example: --mui-customProperties-spacing-a
customProperties: {
borderRadius: {
xs: "4px",
sm: "8px",
md: "16px",
lg: "24px",
},
time: {
normal: "0.35s",
slow: "0.5s",
},
spacing: spacingValues,
borderRadius: borderRadius,
time: time,
},
});

Expand Down
Loading

0 comments on commit 04e4554

Please sign in to comment.