diff --git a/frontend/packages/core/src/AppLayout/drawer.tsx b/frontend/packages/core/src/AppLayout/drawer.tsx
index e06ececf22..88b18ff7de 100644
--- a/frontend/packages/core/src/AppLayout/drawer.tsx
+++ b/frontend/packages/core/src/AppLayout/drawer.tsx
@@ -18,7 +18,6 @@ import { useAppContext } from "../Contexts";
import { useNavigate } from "../navigation";
import type { PopperItemProps } from "../popper";
import { Popper, PopperItem } from "../popper";
-import { THEME_VARIANTS } from "../Theme/colors";
import { filterHiddenRoutes, routesByGrouping, sortedGroupings, workflowByRoute } from "./utils";
@@ -30,9 +29,7 @@ const DrawerPanel = styled(MuiDrawer)(({ theme }: { theme: Theme }) => ({
top: "unset",
width: "inherit",
backgroundColor:
- theme.palette.mode === THEME_VARIANTS.light
- ? theme.palette.contrastColor
- : theme.palette.background.paper,
+ theme.palette.mode === "light" ? theme.palette.contrastColor : theme.palette.background.paper,
boxShadow: `0px 5px 15px ${alpha(theme.palette.primary[400], 0.2)}`,
position: "relative",
display: "flex",
diff --git a/frontend/packages/core/src/AppLayout/theme-switcher.tsx b/frontend/packages/core/src/AppLayout/theme-switcher.tsx
index 0806658f63..c26db3b042 100644
--- a/frontend/packages/core/src/AppLayout/theme-switcher.tsx
+++ b/frontend/packages/core/src/AppLayout/theme-switcher.tsx
@@ -6,18 +6,17 @@ import get from "lodash/get";
import { useUserPreferences } from "../Contexts";
import { Select } from "../Input";
-import { THEME_VARIANTS } from "../Theme/colors";
const ThemeSwitcher = () => {
const { preferences, dispatch } = useUserPreferences();
const options = [
{
- label: THEME_VARIANTS.light,
+ label: "Light",
startAdornment: ,
},
{
- label: THEME_VARIANTS.dark,
+ label: "Dark",
startAdornment: ,
},
];
@@ -25,7 +24,7 @@ const ThemeSwitcher = () => {
const handleOnChange = (value: string) => {
dispatch({
type: "SetPref",
- payload: { key: "theme", value },
+ payload: { key: "theme", value: value.toUpperCase() },
});
};
diff --git a/frontend/packages/core/src/AppProvider/index.tsx b/frontend/packages/core/src/AppProvider/index.tsx
index 5c485883c8..a25bc07eee 100644
--- a/frontend/packages/core/src/AppProvider/index.tsx
+++ b/frontend/packages/core/src/AppProvider/index.tsx
@@ -13,11 +13,12 @@ import { FEATURE_FLAG_POLL_RATE, featureFlags } from "../flags";
import Landing from "../landing";
import type { ClutchError } from "../Network/errors";
import NotFound from "../not-found";
+import { Theme } from "../Theme";
+import type { ThemeOverrides } from "../Theme/types";
import { registeredWorkflows } from "./registrar";
import ShortLinkProxy, { ShortLinkBaseRoute } from "./short-link-proxy";
import ShortLinkStateHydrator from "./short-link-state-hydrator";
-import { Theme } from "./themes";
import type { ConfiguredRoute, Workflow, WorkflowConfiguration } from "./workflow";
import ErrorBoundary from "./workflow";
@@ -76,14 +77,16 @@ interface ClutchAppProps {
[key: string]: () => WorkflowConfiguration;
};
configuration: UserConfiguration;
- appConfiguration: AppConfiguration;
+ appConfiguration?: AppConfiguration;
children?: ClutchAppChild | ClutchAppChild[];
+ themeOverrides?: ThemeOverrides;
}
const ClutchApp = ({
availableWorkflows,
configuration: userConfiguration,
appConfiguration,
+ themeOverrides,
children,
}: ClutchAppProps) => {
const [workflows, setWorkflows] = React.useState([]);
@@ -161,7 +164,7 @@ const ClutchApp = ({
return (
-
+
diff --git a/frontend/packages/core/src/AppProvider/themes.tsx b/frontend/packages/core/src/AppProvider/themes.tsx
deleted file mode 100644
index 1a2b213fdf..0000000000
--- a/frontend/packages/core/src/AppProvider/themes.tsx
+++ /dev/null
@@ -1,45 +0,0 @@
-import React from "react";
-import { useTheme as useMuiTheme } from "@mui/material";
-import type { Theme as MuiTheme } from "@mui/material/styles";
-import get from "lodash/get";
-import isEmpty from "lodash/isEmpty";
-
-import { useUserPreferences } from "../Contexts";
-import { ThemeProvider } from "../Theme";
-import type { ClutchColors } from "../Theme/types";
-import { THEME_VARIANTS } from "../Theme/types";
-
-declare module "@mui/material/styles" {
- interface Theme {
- colors: ClutchColors;
- }
- interface ThemeOptions {
- colors?: ClutchColors;
- }
- interface Palette {
- contrastColor: string;
- headerGradient: string;
- brandColor: string;
- }
-}
-
-const useTheme = () => useMuiTheme() as MuiTheme;
-
-const Theme: React.FC = ({ children }) => {
- const { preferences } = useUserPreferences();
-
- const prefersDarkMode =
- window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches;
-
- const themeVariant = get(preferences, "theme");
-
- const variant = isEmpty(themeVariant)
- ? prefersDarkMode
- ? THEME_VARIANTS.dark
- : THEME_VARIANTS.light
- : themeVariant;
-
- return {children};
-};
-
-export { Theme, useTheme };
diff --git a/frontend/packages/core/src/Charts/linearTimeline.tsx b/frontend/packages/core/src/Charts/linearTimeline.tsx
index 43aee97ed8..72c6dd0560 100644
--- a/frontend/packages/core/src/Charts/linearTimeline.tsx
+++ b/frontend/packages/core/src/Charts/linearTimeline.tsx
@@ -10,7 +10,7 @@ import {
YAxis,
} from "recharts";
-import { useTheme } from "../AppProvider/themes";
+import { useTheme } from "../Theme";
import { calculateDomainEdges, calculateTicks, localTimeFormatter } from "./helpers";
import type { CustomTooltipProps, LinearTimelineData, LinearTimelineStylingProps } from "./types";
@@ -92,9 +92,9 @@ const LinearTimeline = ({
style={{
backgroundColor:
stylingProps?.tooltipBackgroundColor ||
- theme.colors.charts.linearTimeline.tooltipBackgroundColor,
+ theme.chartColors.linearTimeline.tooltipBackgroundColor,
color:
- stylingProps?.tooltipTextColor || theme.colors.charts.linearTimeline.tooltipTextColor,
+ stylingProps?.tooltipTextColor || theme.chartColors.linearTimeline.tooltipTextColor,
}}
>
{localTimeFormatter(payload[0].value)}
@@ -111,9 +111,9 @@ const LinearTimeline = ({
({
- fill: theme.colors.charts.pie.labelPrimary,
+ fill: theme.chartColors.pie.labelPrimary,
}));
const ChartLabelSecondary = styled("text")(({ theme }: { theme: Theme }) => ({
- fill: theme.colors.charts.pie.labelSecondary,
+ fill: theme.chartColors.pie.labelSecondary,
}));
const renderActiveShape = (props, options) => {
diff --git a/frontend/packages/core/src/Theme/colors.tsx b/frontend/packages/core/src/Theme/colors.tsx
index e3e39f9af6..f9d0e3e346 100644
--- a/frontend/packages/core/src/Theme/colors.tsx
+++ b/frontend/packages/core/src/Theme/colors.tsx
@@ -1,244 +1,8 @@
-import type { ClutchColors, ComponentState, ThemeVariant } from "./types";
-
-export enum THEME_VARIANTS {
- light = "light",
- dark = "dark",
-}
+import type { ComponentState, ThemeVariant } from "./types";
+import VARIANTS from "./variants";
export const brandColor = "#02acbe";
-const LIGHT_CHART_COLORS: string[] = [
- "#651FFF",
- "#FF4081",
- "#0091EA",
- "#00695C",
- "#9E9D24",
- "#880E4F",
- "#01579B",
- "#F4511E",
- "#009688",
- "#C2185B",
- "#1A237E",
- "#7C4DFF",
- "#88451D",
- "#AA00FF",
-];
-
-const DARK_CHART_COLORS: string[] = [
- "#651FFF",
- "#FF4081",
- "#0091EA",
- "#00695C",
- "#9E9D24",
- "#880E4F",
- "#01579B",
- "#F4511E",
- "#009688",
- "#C2185B",
- "#1A237E",
- "#7C4DFF",
- "#88451D",
- "#AA00FF",
-];
-
-export const LIGHT_COLORS: ClutchColors = {
- neutral: {
- 50: "#F8F8F9",
- 100: "#F0F1F3",
- 200: "#DBDBE0",
- 300: "#C2C3CB",
- 400: "#9E9FAC",
- 500: "#868798",
- 600: "#56586E",
- 700: "#3D4059",
- 800: "#252845",
- 900: "#0D1030",
- A100: "#0D1030",
- A200: "#0D1030",
- A400: "#0D1030",
- A700: "#0D1030",
- },
- blue: {
- 50: "#F9F9FE",
- 100: "#F5F6FD",
- 200: "#EBEDFB",
- 300: "#D7DAF6",
- 400: "#C2C8F2",
- 500: "#727FE1",
- 600: "#3548D4",
- 700: "#1629B9",
- 800: "#0A1CA6",
- 900: "#011082",
- A100: "#011082",
- A200: "#011082",
- A400: "#011082",
- A700: "#011082",
- },
- green: {
- 50: "#E5FCE8",
- 100: "#CBF7CF",
- 200: "#ACF2B2",
- 300: "#6CD47A",
- 400: "#4AB958",
- 500: "#32A140",
- 600: "#1C872A",
- 700: "#106E1D",
- 800: "#086515",
- 900: "#02590E",
- A100: "#02590E",
- A200: "#02590E",
- A400: "#02590E",
- A700: "#02590E",
- },
- amber: {
- 50: "#FFFBEB",
- 100: "#FEF3C7",
- 200: "#FDE68A",
- 300: "#FCD34D",
- 400: "#FBBF24",
- 500: "#F59E0B",
- 600: "#D97706",
- 700: "#B45309",
- 800: "#92400E",
- 900: "#78350F",
- A100: "#78350F",
- A200: "#78350F",
- A400: "#78350F",
- A700: "#78350F",
- },
- red: {
- 50: "#FFF4F3",
- 100: "#FDDCD2",
- 200: "#F6A996",
- 300: "#F3886E",
- 400: "#F26E50",
- 500: "#F15534",
- 600: "#CA4428",
- 700: "#A1301C",
- 800: "#792111",
- 900: "#571608",
- A100: "#571608",
- A200: "#571608",
- A400: "#571608",
- A700: "#571608",
- },
- charts: {
- common: {
- data: LIGHT_CHART_COLORS,
- },
- pie: {
- labelPrimary: "#0D1030",
- labelSecondary: "#868798",
- },
- linearTimeline: {
- xAxisStroke: "#000",
- tooltipBackgroundColor: "#FFF",
- tooltipTextColor: "#000",
- gridBackgroundColor: "#000",
- gridStroke: "#FFF",
- },
- },
-};
-
-export const DARK_COLORS: ClutchColors = {
- neutral: {
- 50: "#232542",
- 100: "#30324E",
- 200: "#3E4059",
- 300: "#55566D",
- 400: "#77788A",
- 500: "#8D8E9E",
- 600: "#A4A5B1",
- 700: "#D2D2D8",
- 800: "#E8E8EB",
- 900: "#FFFFFF",
- A100: "#FFFFFF",
- A200: "#FFFFFF",
- A400: "#FFFFFF",
- A700: "#FFFFFF",
- },
- blue: {
- 50: "#090A42",
- 100: "#050656",
- 200: "#0A086B",
- 300: "#13199D",
- 400: "#2A4FF6",
- 500: "#4281F6",
- 600: "#5AABF6",
- 700: "#8CC4F8",
- 800: "#C2E1FE",
- 900: "#DCECFB",
- A100: "#DCECFB",
- A200: "#DCECFB",
- A400: "#DCECFB",
- A700: "#DCECFB",
- },
- green: {
- 50: "#002C05",
- 100: "#084713",
- 200: "#145F1D",
- 300: "#217A2A",
- 400: "#2D9638",
- 500: "#54B45B",
- 600: "#73C178",
- 700: "#9CD29E",
- 800: "#C3E4C4",
- 900: "#E6F4E7",
- A100: "#E6F4E7",
- A200: "#E6F4E7",
- A400: "#E6F4E7",
- A700: "#E6F4E7",
- },
- amber: {
- 50: "#352215",
- 100: "#7E3E02",
- 200: "#985304",
- 300: "#B26A08",
- 400: "#CC820D",
- 500: "#E69F2A",
- 600: "#EAB04E",
- 700: "#EFC67F",
- 800: "#F6DCB1",
- 900: "#FBF1E0",
- A100: "#FBF1E0",
- A200: "#FBF1E0",
- A400: "#FBF1E0",
- A700: "#FBF1E0",
- },
- red: {
- 50: "#501306",
- 100: "#621809",
- 200: "#751E0D",
- 300: "#972814",
- 400: "#B3351E",
- 500: "#C8482C",
- 600: "#EB7A60",
- 700: "#F4A08A",
- 800: "#F0B9AB",
- 900: "#FBE8E7",
- A100: "#FFFFFF",
- A200: "#FFFFFF",
- A400: "#FFFFFF",
- A700: "#FFFFFF",
- },
- charts: {
- common: {
- data: DARK_CHART_COLORS,
- },
- pie: {
- labelPrimary: "#0D1030",
- labelSecondary: "#8D8E9E",
- },
- linearTimeline: {
- xAxisStroke: "#FFF",
- tooltipBackgroundColor: "#FFF",
- tooltipTextColor: "#000",
- gridBackgroundColor: "#FFF",
- gridStroke: "#000",
- },
- },
-};
-
export const STATE_OPACITY: { [key in ComponentState]: number } = {
hover: 0.5,
focused: 0.1,
@@ -247,7 +11,6 @@ export const STATE_OPACITY: { [key in ComponentState]: number } = {
disabled: 0.5,
};
-const clutchColors = (variant: ThemeVariant) =>
- variant === THEME_VARIANTS.light ? LIGHT_COLORS : DARK_COLORS;
+const clutchColors = (variant: ThemeVariant) => VARIANTS[variant];
export { clutchColors };
diff --git a/frontend/packages/core/src/Theme/index.tsx b/frontend/packages/core/src/Theme/index.tsx
index a4243fc5bb..b258508970 100644
--- a/frontend/packages/core/src/Theme/index.tsx
+++ b/frontend/packages/core/src/Theme/index.tsx
@@ -1,13 +1,43 @@
+import React from "react";
+import type { Theme as MuiTheme } from "@mui/material";
+import { useTheme as useMuiTheme } from "@mui/material";
import { alpha } from "@mui/material/styles";
+import get from "lodash/get";
+import isEmpty from "lodash/isEmpty";
+
+import { useUserPreferences } from "../Contexts";
import { STATE_OPACITY } from "./colors";
import ThemeProvider from "./theme";
-import type { ComponentState } from "./types";
+import type { ComponentState, ThemeOverrides } from "./types";
+
+interface ThemeProps {
+ children: React.ReactNode;
+ overrides?: ThemeOverrides;
+}
// Return the appropriate color for a specified state and color.
const stateColor = (state: ComponentState, color: string) => {
return alpha(color, STATE_OPACITY[state]);
};
-// TODO: Use the ThemeProvider once the Theme component can be replaced
-export { stateColor, ThemeProvider };
+const useTheme = () => useMuiTheme() as MuiTheme;
+
+const Theme = ({ children, overrides }: ThemeProps) => {
+ const { preferences } = useUserPreferences();
+
+ const prefersDarkMode =
+ window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches;
+
+ const themeVariant = get(preferences, "theme");
+
+ const variant = isEmpty(themeVariant) ? (prefersDarkMode ? "DARK" : "LIGHT") : themeVariant;
+
+ return (
+
+ {children}
+
+ );
+};
+
+export { Theme, useTheme, stateColor, ThemeProvider };
diff --git a/frontend/packages/core/src/Theme/palette.tsx b/frontend/packages/core/src/Theme/palette.tsx
index 4b7ecb457e..6e10db1109 100644
--- a/frontend/packages/core/src/Theme/palette.tsx
+++ b/frontend/packages/core/src/Theme/palette.tsx
@@ -1,38 +1,30 @@
-import type { PaletteOptions as MuiPaletteOptions } from "@mui/material/styles";
import { alpha, TypeText } from "@mui/material/styles";
-import { brandColor, DARK_COLORS, LIGHT_COLORS, THEME_VARIANTS } from "./colors";
-import type { ClutchColors, ThemeVariant } from "./types";
-
-interface PaletteOptions extends MuiPaletteOptions {
- type: ThemeVariant;
- contrastColor: string;
- headerGradient: string;
- brandColor: string;
-}
+import { brandColor } from "./colors";
+import type { ClutchColors, PaletteOptions, ThemeVariant } from "./types";
+import VARIANTS from "./variants";
const lightText: Partial = {
- primary: LIGHT_COLORS.neutral[900],
- secondary: alpha(LIGHT_COLORS.neutral[900], 0.65),
+ primary: VARIANTS.LIGHT.colors.neutral[900],
+ secondary: alpha(VARIANTS.LIGHT.colors.neutral[900], 0.65),
// tertiary
// inverse
};
const darkText: Partial = {
- primary: alpha(DARK_COLORS.neutral[900], 0.9),
- secondary: alpha(DARK_COLORS.neutral[900], 0.75),
+ primary: alpha(VARIANTS.DARK.colors.neutral[900], 0.9),
+ secondary: alpha(VARIANTS.DARK.colors.neutral[900], 0.75),
// tertiary
// inverse
};
const palette = (variant: ThemeVariant): PaletteOptions => {
- const isLightMode = variant === THEME_VARIANTS.light;
- const color = (isLightMode ? LIGHT_COLORS : DARK_COLORS) as ClutchColors;
+ const isLightMode = variant === "LIGHT";
+ const color = (isLightMode ? VARIANTS.LIGHT.colors : VARIANTS.DARK.colors) as ClutchColors;
- // TODO: add all clutch colors to "common colors"
return {
type: variant,
- mode: variant,
+ mode: (variant === "LIGHT" ? "light" : "dark") as PaletteOptions["mode"],
brandColor,
primary: color.blue,
secondary: color.neutral,
diff --git a/frontend/packages/core/src/Theme/theme.tsx b/frontend/packages/core/src/Theme/theme.tsx
index d2ea3cd33e..4007608cc7 100644
--- a/frontend/packages/core/src/Theme/theme.tsx
+++ b/frontend/packages/core/src/Theme/theme.tsx
@@ -6,19 +6,43 @@ import {
StyledEngineProvider,
ThemeProvider as MuiThemeProvider,
} from "@mui/material";
+import { defaultsDeep } from "lodash";
-import { clutchColors, THEME_VARIANTS } from "./colors";
+import { clutchColors } from "./colors";
import palette from "./palette";
-import type { ThemeVariant } from "./types";
+import type {
+ ChartColors,
+ ClutchColors,
+ CustomClutchTheme,
+ ThemeOverrides,
+ ThemeVariant,
+} from "./types";
declare module "@emotion/react" {
export interface Theme extends MuiTheme {}
}
-// Create a Material UI theme is propagated to all children.
-const createTheme = (variant: ThemeVariant): MuiTheme => {
+declare module "@mui/material/styles" {
+ interface Theme {
+ colors: ClutchColors;
+ chartColors: ChartColors;
+ }
+ interface ThemeOptions {
+ colors?: ClutchColors;
+ chartColors?: ChartColors;
+ }
+ interface Palette {
+ contrastColor: string;
+ headerGradient: string;
+ brandColor: string;
+ }
+}
+
+const defaultTheme = (variant: ThemeVariant): MuiTheme => {
+ const { colors, chartColors } = clutchColors(variant);
return createMuiTheme({
- colors: clutchColors(variant),
+ colors,
+ chartColors,
palette: palette(variant),
transitions: {
// https://material-ui.com/getting-started/faq/#how-can-i-disable-transitions-globally
@@ -69,14 +93,30 @@ const createTheme = (variant: ThemeVariant): MuiTheme => {
});
};
+const generateTheme = (variant: ThemeVariant, theme?: CustomClutchTheme): MuiTheme => {
+ const baseTheme = defaultTheme(variant);
+ if (!theme) {
+ return baseTheme;
+ }
+ const { colors, chartColors, palette: basePalette, ...rest } = baseTheme;
+
+ return createMuiTheme({
+ colors: defaultsDeep(theme.colors ?? {}, colors),
+ chartColors: defaultsDeep(theme.chartColors ?? {}, chartColors),
+ palette: defaultsDeep(theme?.palette ?? {}, basePalette),
+ ...defaultsDeep(theme?.themeOptions ?? {}, rest),
+ });
+};
+
interface ThemeProps {
variant?: ThemeVariant;
children: React.ReactNode;
+ overrides?: ThemeOverrides;
}
-const ThemeProvider = ({ children, variant = THEME_VARIANTS.light }: ThemeProps) => (
+const ThemeProvider = ({ children, variant, overrides = {} }: ThemeProps) => (
-
+
{children}
diff --git a/frontend/packages/core/src/Theme/types.tsx b/frontend/packages/core/src/Theme/types.tsx
index 7b224cf3a7..4c9cef7bae 100644
--- a/frontend/packages/core/src/Theme/types.tsx
+++ b/frontend/packages/core/src/Theme/types.tsx
@@ -1,11 +1,9 @@
-import type { Color } from "@mui/material";
+import type { Color, Theme as MuiTheme } from "@mui/material";
+import type { PaletteOptions as MuiPaletteOptions } from "@mui/material/styles";
-export type ThemeVariant = "light" | "dark";
+import type VARIANTS from "./variants";
-export enum THEME_VARIANTS {
- light = "light",
- dark = "dark",
-}
+export type ThemeVariant = keyof typeof VARIANTS;
export interface StrokeColor {
primary: string;
@@ -14,21 +12,13 @@ export interface StrokeColor {
inverse: string;
}
-export interface ChartColors {
- common: {
- data: string[];
- };
- pie: {
- labelPrimary: string;
- labelSecondary: string;
- };
- linearTimeline: {
- xAxisStroke: string;
- tooltipBackgroundColor: string;
- tooltipTextColor: string;
- gridBackgroundColor: string;
- gridStroke: string;
- };
+export interface ThemeOptions extends MuiTheme {}
+
+export interface PaletteOptions extends MuiPaletteOptions {
+ type: ThemeVariant;
+ contrastColor: string;
+ headerGradient: string;
+ brandColor: string;
}
export interface ClutchColors {
@@ -37,7 +27,62 @@ export interface ClutchColors {
green: Color;
amber: Color;
red: Color;
- charts: ChartColors;
}
+interface CommonChartColors {
+ data: string[];
+}
+
+interface PieChartColors {
+ labelPrimary: string;
+ labelSecondary: string;
+}
+
+interface TimelineChartColors {
+ xAxisStroke: string;
+ tooltipBackgroundColor: string;
+ tooltipTextColor: string;
+ gridBackgroundColor: string;
+ gridStroke: string;
+}
+
+export interface ChartColors {
+ common: CommonChartColors;
+ pie: PieChartColors;
+ linearTimeline: TimelineChartColors;
+}
+
+export interface ClutchTheme {
+ colors: ClutchColors;
+ chartColors: ChartColors;
+}
+
+type Partial = {
+ [P in keyof T]?: T[P];
+};
+
+export type CustomClutchColor = Partial;
+export type CustomClutchColors = {
+ [P in keyof ClutchColors]?: CustomClutchColor;
+};
+export type CustomChartColors = {
+ [P in keyof ChartColors]?: Partial;
+};
+export type CustomPalette = {
+ [P in keyof PaletteOptions]?: Partial;
+};
+export type CustomThemeOptions = {
+ [P in keyof ThemeOptions]?: Partial;
+};
+export interface CustomClutchTheme {
+ colors?: CustomClutchColors;
+ chartColors?: CustomChartColors;
+ palette?: CustomPalette;
+ themeOptions?: CustomThemeOptions;
+}
+
+export type ThemeOverrides = {
+ [P in ThemeVariant]?: CustomClutchTheme;
+};
+
export type ComponentState = "hover" | "focused" | "pressed" | "selected" | "disabled";
diff --git a/frontend/packages/core/src/Theme/variants/dark/chart.tsx b/frontend/packages/core/src/Theme/variants/dark/chart.tsx
new file mode 100644
index 0000000000..1caf271a66
--- /dev/null
+++ b/frontend/packages/core/src/Theme/variants/dark/chart.tsx
@@ -0,0 +1,37 @@
+import type { ChartColors } from "../../types";
+
+const COLORS: string[] = [
+ "#651FFF",
+ "#FF4081",
+ "#0091EA",
+ "#00695C",
+ "#9E9D24",
+ "#880E4F",
+ "#01579B",
+ "#F4511E",
+ "#009688",
+ "#C2185B",
+ "#1A237E",
+ "#7C4DFF",
+ "#88451D",
+ "#AA00FF",
+];
+
+const chartColors: ChartColors = {
+ common: {
+ data: COLORS,
+ },
+ pie: {
+ labelPrimary: "#0D1030",
+ labelSecondary: "#8D8E9E",
+ },
+ linearTimeline: {
+ xAxisStroke: "#FFF",
+ tooltipBackgroundColor: "#FFF",
+ tooltipTextColor: "#000",
+ gridBackgroundColor: "#FFF",
+ gridStroke: "#000",
+ },
+};
+
+export default chartColors;
diff --git a/frontend/packages/core/src/Theme/variants/dark/colors.tsx b/frontend/packages/core/src/Theme/variants/dark/colors.tsx
new file mode 100644
index 0000000000..0a59b93514
--- /dev/null
+++ b/frontend/packages/core/src/Theme/variants/dark/colors.tsx
@@ -0,0 +1,98 @@
+import type { Color } from "@mui/material";
+
+import type { ClutchColors } from "../../types";
+
+const neutral: Color = {
+ 50: "#232542",
+ 100: "#30324E",
+ 200: "#3E4059",
+ 300: "#55566D",
+ 400: "#77788A",
+ 500: "#8D8E9E",
+ 600: "#A4A5B1",
+ 700: "#D2D2D8",
+ 800: "#E8E8EB",
+ 900: "#FFFFFF",
+ A100: "#FFFFFF",
+ A200: "#FFFFFF",
+ A400: "#FFFFFF",
+ A700: "#FFFFFF",
+};
+
+const blue: Color = {
+ 50: "#090A42",
+ 100: "#050656",
+ 200: "#0A086B",
+ 300: "#13199D",
+ 400: "#2A4FF6",
+ 500: "#4281F6",
+ 600: "#5AABF6",
+ 700: "#8CC4F8",
+ 800: "#C2E1FE",
+ 900: "#DCECFB",
+ A100: "#DCECFB",
+ A200: "#DCECFB",
+ A400: "#DCECFB",
+ A700: "#DCECFB",
+};
+
+const green: Color = {
+ 50: "#002C05",
+ 100: "#084713",
+ 200: "#145F1D",
+ 300: "#217A2A",
+ 400: "#2D9638",
+ 500: "#54B45B",
+ 600: "#73C178",
+ 700: "#9CD29E",
+ 800: "#C3E4C4",
+ 900: "#E6F4E7",
+ A100: "#E6F4E7",
+ A200: "#E6F4E7",
+ A400: "#E6F4E7",
+ A700: "#E6F4E7",
+};
+
+const amber: Color = {
+ 50: "#352215",
+ 100: "#7E3E02",
+ 200: "#985304",
+ 300: "#B26A08",
+ 400: "#CC820D",
+ 500: "#E69F2A",
+ 600: "#EAB04E",
+ 700: "#EFC67F",
+ 800: "#F6DCB1",
+ 900: "#FBF1E0",
+ A100: "#FBF1E0",
+ A200: "#FBF1E0",
+ A400: "#FBF1E0",
+ A700: "#FBF1E0",
+};
+
+const red: Color = {
+ 50: "#501306",
+ 100: "#621809",
+ 200: "#751E0D",
+ 300: "#972814",
+ 400: "#B3351E",
+ 500: "#C8482C",
+ 600: "#EB7A60",
+ 700: "#F4A08A",
+ 800: "#F0B9AB",
+ 900: "#FBE8E7",
+ A100: "#FFFFFF",
+ A200: "#FFFFFF",
+ A400: "#FFFFFF",
+ A700: "#FFFFFF",
+};
+
+const colors: ClutchColors = {
+ neutral,
+ blue,
+ green,
+ amber,
+ red,
+};
+
+export default colors;
diff --git a/frontend/packages/core/src/Theme/variants/dark/index.tsx b/frontend/packages/core/src/Theme/variants/dark/index.tsx
new file mode 100644
index 0000000000..9fc7906011
--- /dev/null
+++ b/frontend/packages/core/src/Theme/variants/dark/index.tsx
@@ -0,0 +1,11 @@
+import type { ClutchTheme } from "../../types";
+
+import chartColors from "./chart";
+import colors from "./colors";
+
+const DARK_THEME: ClutchTheme = {
+ chartColors,
+ colors,
+};
+
+export default DARK_THEME;
diff --git a/frontend/packages/core/src/Theme/variants/index.tsx b/frontend/packages/core/src/Theme/variants/index.tsx
new file mode 100644
index 0000000000..3f32e54727
--- /dev/null
+++ b/frontend/packages/core/src/Theme/variants/index.tsx
@@ -0,0 +1,9 @@
+import DARK_THEME from "./dark";
+import LIGHT_THEME from "./light";
+
+const VARIANTS = {
+ DARK: DARK_THEME,
+ LIGHT: LIGHT_THEME,
+};
+
+export default VARIANTS;
diff --git a/frontend/packages/core/src/Theme/variants/light/chart.tsx b/frontend/packages/core/src/Theme/variants/light/chart.tsx
new file mode 100644
index 0000000000..0b451185df
--- /dev/null
+++ b/frontend/packages/core/src/Theme/variants/light/chart.tsx
@@ -0,0 +1,37 @@
+import type { ChartColors } from "../../types";
+
+const COLORS: string[] = [
+ "#651FFF",
+ "#FF4081",
+ "#0091EA",
+ "#00695C",
+ "#9E9D24",
+ "#880E4F",
+ "#01579B",
+ "#F4511E",
+ "#009688",
+ "#C2185B",
+ "#1A237E",
+ "#7C4DFF",
+ "#88451D",
+ "#AA00FF",
+];
+
+const chartColors: ChartColors = {
+ common: {
+ data: COLORS,
+ },
+ pie: {
+ labelPrimary: "#0D1030",
+ labelSecondary: "#868798",
+ },
+ linearTimeline: {
+ xAxisStroke: "#000",
+ tooltipBackgroundColor: "#FFF",
+ tooltipTextColor: "#000",
+ gridBackgroundColor: "#000",
+ gridStroke: "#FFF",
+ },
+};
+
+export default chartColors;
diff --git a/frontend/packages/core/src/Theme/variants/light/colors.tsx b/frontend/packages/core/src/Theme/variants/light/colors.tsx
new file mode 100644
index 0000000000..307df39bce
--- /dev/null
+++ b/frontend/packages/core/src/Theme/variants/light/colors.tsx
@@ -0,0 +1,98 @@
+import type { Color } from "@mui/material";
+
+import type { ClutchColors } from "../../types";
+
+const neutral: Color = {
+ 50: "#F8F8F9",
+ 100: "#F0F1F3",
+ 200: "#DBDBE0",
+ 300: "#C2C3CB",
+ 400: "#9E9FAC",
+ 500: "#868798",
+ 600: "#56586E",
+ 700: "#3D4059",
+ 800: "#252845",
+ 900: "#0D1030",
+ A100: "#0D1030",
+ A200: "#0D1030",
+ A400: "#0D1030",
+ A700: "#0D1030",
+};
+
+const blue: Color = {
+ 50: "#F9F9FE",
+ 100: "#F5F6FD",
+ 200: "#EBEDFB",
+ 300: "#D7DAF6",
+ 400: "#C2C8F2",
+ 500: "#727FE1",
+ 600: "#3548D4",
+ 700: "#1629B9",
+ 800: "#0A1CA6",
+ 900: "#011082",
+ A100: "#011082",
+ A200: "#011082",
+ A400: "#011082",
+ A700: "#011082",
+};
+
+const green: Color = {
+ 50: "#E5FCE8",
+ 100: "#CBF7CF",
+ 200: "#ACF2B2",
+ 300: "#6CD47A",
+ 400: "#4AB958",
+ 500: "#32A140",
+ 600: "#1C872A",
+ 700: "#106E1D",
+ 800: "#086515",
+ 900: "#02590E",
+ A100: "#02590E",
+ A200: "#02590E",
+ A400: "#02590E",
+ A700: "#02590E",
+};
+
+const amber: Color = {
+ 50: "#FFFBEB",
+ 100: "#FEF3C7",
+ 200: "#FDE68A",
+ 300: "#FCD34D",
+ 400: "#FBBF24",
+ 500: "#F59E0B",
+ 600: "#D97706",
+ 700: "#B45309",
+ 800: "#92400E",
+ 900: "#78350F",
+ A100: "#78350F",
+ A200: "#78350F",
+ A400: "#78350F",
+ A700: "#78350F",
+};
+
+const red: Color = {
+ 50: "#FFF4F3",
+ 100: "#FDDCD2",
+ 200: "#F6A996",
+ 300: "#F3886E",
+ 400: "#F26E50",
+ 500: "#F15534",
+ 600: "#CA4428",
+ 700: "#A1301C",
+ 800: "#792111",
+ 900: "#571608",
+ A100: "#571608",
+ A200: "#571608",
+ A400: "#571608",
+ A700: "#571608",
+};
+
+const colors: ClutchColors = {
+ neutral,
+ blue,
+ green,
+ amber,
+ red,
+};
+
+export default colors;
diff --git a/frontend/packages/core/src/Theme/variants/light/index.tsx b/frontend/packages/core/src/Theme/variants/light/index.tsx
new file mode 100644
index 0000000000..b1ba04dcad
--- /dev/null
+++ b/frontend/packages/core/src/Theme/variants/light/index.tsx
@@ -0,0 +1,11 @@
+import type { ClutchTheme } from "../../types";
+
+import chartColors from "./chart";
+import colors from "./colors";
+
+const LIGHT: ClutchTheme = {
+ chartColors,
+ colors,
+};
+
+export default LIGHT;
diff --git a/frontend/packages/core/src/index.tsx b/frontend/packages/core/src/index.tsx
index 66a6be3013..fe86f5739e 100644
--- a/frontend/packages/core/src/index.tsx
+++ b/frontend/packages/core/src/index.tsx
@@ -59,8 +59,7 @@ export { default as Code } from "./text";
export { default as TimeAgo } from "./timeago";
export { Typography } from "./typography";
export { default as ClutchApp } from "./AppProvider";
-export { useTheme } from "./AppProvider/themes";
-export { ThemeProvider } from "./Theme";
+export { ThemeProvider, useTheme } from "./Theme";
export { css as EMOTION_CSS, keyframes as EMOTION_KEYFRAMES } from "@emotion/react";
@@ -77,3 +76,12 @@ export type { WorkflowRemoveDataFn, WorkflowRetrieveDataFn, WorkflowStoreDataFn
export type { ClutchError } from "./Network/errors";
export type { TypographyProps } from "./typography";
export type { StyledComponent } from "@emotion/styled";
+export type {
+ CustomClutchColor,
+ CustomClutchColors,
+ CustomChartColors,
+ CustomPalette,
+ CustomThemeOptions,
+ CustomClutchTheme,
+ ThemeOverrides,
+} from "./Theme/types";
diff --git a/frontend/packages/core/src/landing.tsx b/frontend/packages/core/src/landing.tsx
index 888fc21f98..5421494916 100644
--- a/frontend/packages/core/src/landing.tsx
+++ b/frontend/packages/core/src/landing.tsx
@@ -6,7 +6,6 @@ import Typography from "@mui/material/Typography";
import { userId } from "./AppLayout/user";
import { workflowsByTrending } from "./AppLayout/utils";
import { MonsterGraphic } from "./Assets/Graphics";
-import { THEME_VARIANTS } from "./Theme/colors";
import { LandingCard } from "./card";
import { useAppContext } from "./Contexts";
import { useNavigate } from "./navigation";
@@ -18,9 +17,7 @@ const StyledLanding = styled.div(({ theme }: { theme: Theme }) => ({
"& .welcome": {
display: "flex",
backgroundColor:
- theme.palette.mode === THEME_VARIANTS.light
- ? theme.palette.contrastColor
- : theme.palette.background.paper,
+ theme.palette.mode === "light" ? theme.palette.contrastColor : theme.palette.background.paper,
padding: "32px 80px",
},
diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json
index 7c66de43f4..802466ab83 100644
--- a/frontend/tsconfig.json
+++ b/frontend/tsconfig.json
@@ -1,6 +1,7 @@
{
"extends": "./tsconfig.base.json",
"compilerOptions": {
+ "composite": false,
"outDir": "dist",
"paths": {
"@clutch-sh/*": ["api/*", "packages/*/src", "workflows/*/src"]
diff --git a/tools/setup-git-hooks.sh b/tools/setup-git-hooks.sh
index 8481c6d3d2..7a165a73d7 100755
--- a/tools/setup-git-hooks.sh
+++ b/tools/setup-git-hooks.sh
@@ -13,5 +13,7 @@ fi
GITHUB_ROOT="${SCRIPT_ROOT}/.github"
GIT_REPO_ROOT="${REPO_ROOT}/.git"
-echo "Setting up git pre-commit hooks for ${REPO_ROOT}"
-ln -s -f "${GITHUB_ROOT}/hooks/pre-commit" "${GIT_REPO_ROOT}/hooks/pre-commit"
+if [[ -f "${GITHUB_ROOT}/hooks/pre-commit" && -f "${GIT_REPO_ROOT}/hooks/pre-commit" ]]; then
+ echo "Setting up git pre-commit hooks for ${REPO_ROOT}"
+ ln -s -f "${GITHUB_ROOT}/hooks/pre-commit" "${GIT_REPO_ROOT}/hooks/pre-commit"
+fi