From 04e45546b30c168fcf0d0161bd3b8476e823b750 Mon Sep 17 00:00:00 2001 From: Luis Doebbel Date: Mon, 23 Sep 2024 09:36:50 -0400 Subject: [PATCH 1/2] Theme customization and typing. Some values used in both MUI theme and custom css. --- .../errorHelperText/ErrorHelperText.tsx | 28 +++++++-- .../src/app/components/loading/Loading.tsx | 15 ++++- .../app/components/loading/loading.module.css | 10 --- .../src/app/components/spinner/Spinner.tsx | 2 +- frontend/src/material-ui-pigment-css.d.ts | 52 ++++++++++------ frontend/src/styles/_fonts.scss | 39 ++++++++++++ frontend/src/styles/_globals.scss | 4 +- frontend/src/styles/_variables.scss | 19 +++--- frontend/src/styles/index.scss | 2 + frontend/src/themes/palette.ts | 4 +- frontend/src/themes/theme.ts | 46 +++++++------- frontend/src/themes/typography.ts | 61 +++++++++++++++++++ frontend/src/themes/variables.ts | 39 ++++++++++++ 13 files changed, 245 insertions(+), 76 deletions(-) create mode 100644 frontend/src/styles/_fonts.scss create mode 100644 frontend/src/themes/typography.ts create mode 100644 frontend/src/themes/variables.ts diff --git a/frontend/src/app/components/errorHelperText/ErrorHelperText.tsx b/frontend/src/app/components/errorHelperText/ErrorHelperText.tsx index b312da2..c469b37 100644 --- a/frontend/src/app/components/errorHelperText/ErrorHelperText.tsx +++ b/frontend/src/app/components/errorHelperText/ErrorHelperText.tsx @@ -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( undefined, @@ -21,10 +39,10 @@ export default function ErrorHelperText({ message }: IErrorBox) { {activeMessage && ( ({ + 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; @@ -16,9 +27,9 @@ export default function Loading({ isLoading = true }: ILoading) { ({ - 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)`, diff --git a/frontend/src/material-ui-pigment-css.d.ts b/frontend/src/material-ui-pigment-css.d.ts index 7525cc4..c2f69c7 100644 --- a/frontend/src/material-ui-pigment-css.d.ts +++ b/frontend/src/material-ui-pigment-css.d.ts @@ -1,6 +1,7 @@ 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; @@ -8,25 +9,42 @@ declare module "@mui/material-pigment-css" { } 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; }; } @@ -34,20 +52,14 @@ declare module "@mui/material/styles" { interface ThemeOptions { zIndex?: Partial; customProperties?: { - borderRadius?: { - xs: string; - sm: string; - md: string; - lg: string; - }; - time?: { - normal: string; - slow: string; - }; + spacing?: Partial; + borderRadius?: Partial; + time?: Partial; }; } } +// Allows typescript to recognize sx prop on HTML elements declare global { namespace React { interface HTMLAttributes { diff --git a/frontend/src/styles/_fonts.scss b/frontend/src/styles/_fonts.scss new file mode 100644 index 0000000..2ba2fc0 --- /dev/null +++ b/frontend/src/styles/_fonts.scss @@ -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"); +} diff --git a/frontend/src/styles/_globals.scss b/frontend/src/styles/_globals.scss index f6c2f8f..9586310 100755 --- a/frontend/src/styles/_globals.scss +++ b/frontend/src/styles/_globals.scss @@ -12,8 +12,6 @@ body { flex-direction: column; min-height: 100%; width: 100%; - font-family: InterTight, sans-serif; - font-size: 16px; overflow-y: scroll; } @@ -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 { diff --git a/frontend/src/styles/_variables.scss b/frontend/src/styles/_variables.scss index 7c338bc..7440938 100755 --- a/frontend/src/styles/_variables.scss +++ b/frontend/src/styles/_variables.scss @@ -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: ( diff --git a/frontend/src/styles/index.scss b/frontend/src/styles/index.scss index 9dd8729..3123479 100755 --- a/frontend/src/styles/index.scss +++ b/frontend/src/styles/index.scss @@ -6,4 +6,6 @@ @forward "export"; +@forward "fonts"; + @forward "globals"; diff --git a/frontend/src/themes/palette.ts b/frontend/src/themes/palette.ts index 3f98f15..ececd60 100644 --- a/frontend/src/themes/palette.ts +++ b/frontend/src/themes/palette.ts @@ -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: { diff --git a/frontend/src/themes/theme.ts b/frontend/src/themes/theme.ts index 795f214..13162f3 100644 --- a/frontend/src/themes/theme.ts +++ b/frontend/src/themes/theme.ts @@ -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, }, }); diff --git a/frontend/src/themes/typography.ts b/frontend/src/themes/typography.ts new file mode 100644 index 0000000..831eb47 --- /dev/null +++ b/frontend/src/themes/typography.ts @@ -0,0 +1,61 @@ +import { TypographyOptions } from "@mui/material/styles/createTypography"; + +const typography: TypographyOptions = { + fontFamily: "InterTight", + h1: { + fontSize: "2.5rem", + fontWeight: 600, + }, + h2: { + fontSize: "2rem", + fontWeight: 600, + }, + h3: { + fontSize: "1.75rem", + fontWeight: 600, + }, + h4: { + fontSize: "1.5rem", + fontWeight: 600, + }, + h5: { + fontSize: "1.25rem", + fontWeight: 600, + }, + h6: { + fontSize: "1rem", + fontWeight: 600, + }, + subtitle1: { + fontSize: "1rem", + fontWeight: 400, + }, + subtitle2: { + fontSize: "0.875rem", + fontWeight: 400, + }, + body1: { + fontSize: "1rem", + fontWeight: 400, + }, + body2: { + fontSize: "0.875rem", + fontWeight: 400, + }, + button: { + fontSize: "1rem", + fontWeight: 600, + textTransform: "none", + }, + caption: { + fontSize: "0.75rem", + fontWeight: 400, + }, + overline: { + fontSize: "0.75rem", + fontWeight: 600, + textTransform: "uppercase", + }, +}; + +export default typography; diff --git a/frontend/src/themes/variables.ts b/frontend/src/themes/variables.ts new file mode 100644 index 0000000..ddc2b5f --- /dev/null +++ b/frontend/src/themes/variables.ts @@ -0,0 +1,39 @@ +import { CustomBorderRadius, CustomSpacing, CustomTime } from "@mui/material"; +import { BreakpointsOptions, ZIndex } from "@mui/material/styles"; + +export const breakpoints: BreakpointsOptions["values"] = { + xs: 640, + sm: 768, + md: 1024, + lg: 1280, + xl: 1440, +}; + +export const zIndex: Partial = { + debugBanner: 100, + cookieBanner: 200, + loading: 1000, +}; + +export const spacingValues: CustomSpacing = { + a: "auto", + xxs: "0.25rem", + xs: "0.5rem", + sm: "0.75rem", + md: "1rem", + lg: "1.5rem", + xl: "2rem", + xxl: "3rem", +}; + +export const borderRadius: CustomBorderRadius = { + xs: "4px", + sm: "8px", + md: "16px", + lg: "24px", +}; + +export const time: CustomTime = { + normal: "0.35s", + slow: "0.5s", +}; From 89e6fb66424e34ae2e4ea4a1cb0dca09b294594b Mon Sep 17 00:00:00 2001 From: Luis Doebbel Date: Mon, 23 Sep 2024 10:04:20 -0400 Subject: [PATCH 2/2] Animation times use properties defined in theme --- .../error-helper-text.module.css | 21 ----------------- frontend/src/material-ui-pigment-css.d.ts | 7 ------ frontend/src/styles/_animations.scss | 23 ------------------- frontend/src/styles/_globals.scss | 1 - frontend/src/styles/index.scss | 2 -- frontend/src/themes/theme.ts | 9 +------- frontend/src/themes/variables.ts | 7 +----- 7 files changed, 2 insertions(+), 68 deletions(-) delete mode 100644 frontend/src/app/components/errorHelperText/error-helper-text.module.css delete mode 100644 frontend/src/styles/_animations.scss diff --git a/frontend/src/app/components/errorHelperText/error-helper-text.module.css b/frontend/src/app/components/errorHelperText/error-helper-text.module.css deleted file mode 100644 index b1531b0..0000000 --- a/frontend/src/app/components/errorHelperText/error-helper-text.module.css +++ /dev/null @@ -1,21 +0,0 @@ -.enter { - opacity: 0; -} - -.enter-active { - opacity: 1; - /* - The time here is found in the theme.customProperties.time property. - Ideally we should be getting this value dynamically, from the theme. - */ - transition: opacity 0.35s ease-in; -} - -.exit { - opacity: 1; -} - -.exit-active { - opacity: 0; - transition: opacity 0.35s ease-out; -} diff --git a/frontend/src/material-ui-pigment-css.d.ts b/frontend/src/material-ui-pigment-css.d.ts index c2f69c7..d8ccce6 100644 --- a/frontend/src/material-ui-pigment-css.d.ts +++ b/frontend/src/material-ui-pigment-css.d.ts @@ -34,17 +34,11 @@ declare module "@mui/material/styles" { lg: string; } - interface CustomTime { - normal: string; - slow: string; - } - interface Theme { zIndex: ZIndex; customProperties: { spacing: CustomSpacing; borderRadius: CustomBorderRadius; - time: Partial; }; } @@ -54,7 +48,6 @@ declare module "@mui/material/styles" { customProperties?: { spacing?: Partial; borderRadius?: Partial; - time?: Partial; }; } } diff --git a/frontend/src/styles/_animations.scss b/frontend/src/styles/_animations.scss deleted file mode 100644 index f57205b..0000000 --- a/frontend/src/styles/_animations.scss +++ /dev/null @@ -1,23 +0,0 @@ -/* ============================================ -= Animations = -============================================ */ - -@keyframes fade-in { - from { - opacity: 0; - } - - to { - opacity: 1; - } -} - -@keyframes rotate { - from { - transform: rotate(0deg); - } - - to { - transform: rotate(360deg); - } -} diff --git a/frontend/src/styles/_globals.scss b/frontend/src/styles/_globals.scss index 9586310..68755fe 100755 --- a/frontend/src/styles/_globals.scss +++ b/frontend/src/styles/_globals.scss @@ -21,7 +21,6 @@ body { flex: 1 1 auto; height: 100%; width: 100%; - animation: var(--mui-customProperties-time-slow) fade-in forwards; } .flex { diff --git a/frontend/src/styles/index.scss b/frontend/src/styles/index.scss index 3123479..bc3e9f4 100755 --- a/frontend/src/styles/index.scss +++ b/frontend/src/styles/index.scss @@ -2,8 +2,6 @@ @forward "vendors/toastify.css"; -@forward "animations"; - @forward "export"; @forward "fonts"; diff --git a/frontend/src/themes/theme.ts b/frontend/src/themes/theme.ts index 13162f3..93bf7c4 100644 --- a/frontend/src/themes/theme.ts +++ b/frontend/src/themes/theme.ts @@ -1,13 +1,7 @@ import { createTheme } from "@mui/material/styles"; import palette from "./palette"; import typography from "./typography"; -import { - breakpoints, - zIndex, - spacingValues, - borderRadius, - time, -} from "./variables"; +import { breakpoints, zIndex, spacingValues, borderRadius } from "./variables"; const theme = createTheme({ cssVariables: true, // creates css variables for theme values @@ -28,7 +22,6 @@ const theme = createTheme({ customProperties: { spacing: spacingValues, borderRadius: borderRadius, - time: time, }, }); diff --git a/frontend/src/themes/variables.ts b/frontend/src/themes/variables.ts index ddc2b5f..2f4a658 100644 --- a/frontend/src/themes/variables.ts +++ b/frontend/src/themes/variables.ts @@ -1,4 +1,4 @@ -import { CustomBorderRadius, CustomSpacing, CustomTime } from "@mui/material"; +import { CustomBorderRadius, CustomSpacing } from "@mui/material"; import { BreakpointsOptions, ZIndex } from "@mui/material/styles"; export const breakpoints: BreakpointsOptions["values"] = { @@ -32,8 +32,3 @@ export const borderRadius: CustomBorderRadius = { md: "16px", lg: "24px", }; - -export const time: CustomTime = { - normal: "0.35s", - slow: "0.5s", -};