First Commit
This commit is contained in:
@@ -0,0 +1,310 @@
|
||||
import { alpha, createTheme, darken, lighten } from "@mui/material/styles";
|
||||
|
||||
type PaletteLike = Record<string, any>;
|
||||
|
||||
function buildPrimary(main: string) {
|
||||
return {
|
||||
lighter: lighten(main, 0.82),
|
||||
light: lighten(main, 0.56),
|
||||
main,
|
||||
dark: darken(main, 0.22),
|
||||
darker: darken(main, 0.72),
|
||||
};
|
||||
}
|
||||
|
||||
function buildLightPalette(accentColor: string): PaletteLike {
|
||||
const textPrimary = "#1B1B1F";
|
||||
const textSecondary = "#46464F";
|
||||
|
||||
const secondaryMain = "#5A5C78";
|
||||
const divider = "#EFEDF4";
|
||||
const background = "#FFFFFF";
|
||||
|
||||
const disabled = "#777680";
|
||||
const disabledBackground = "#E4E1E6";
|
||||
|
||||
return {
|
||||
primary: buildPrimary(accentColor || "#606BDF"),
|
||||
secondary: {
|
||||
lighter: "#E0E0FF",
|
||||
light: "#C3C4E4",
|
||||
main: secondaryMain,
|
||||
dark: "#43455F",
|
||||
darker: "#171A31",
|
||||
},
|
||||
error: {
|
||||
lighter: "#FFEDEA",
|
||||
light: "#FFDAD6",
|
||||
main: "#DE3730",
|
||||
dark: "#BA1A1A",
|
||||
darker: "#690005",
|
||||
},
|
||||
warning: {
|
||||
lighter: "#FFEEE1",
|
||||
light: "#FFDCBE",
|
||||
main: "#AE6600",
|
||||
dark: "#8B5000",
|
||||
darker: "#4A2800",
|
||||
},
|
||||
success: {
|
||||
lighter: "#C8FFC0",
|
||||
light: "#B6F2AF",
|
||||
main: "#22892F",
|
||||
dark: "#006E1C",
|
||||
darker: "#00390A",
|
||||
},
|
||||
info: {
|
||||
lighter: "#D4F7FF",
|
||||
light: "#A1EFFF",
|
||||
main: "#008394",
|
||||
dark: "#006876",
|
||||
darker: "#00363E",
|
||||
},
|
||||
grey: {
|
||||
50: "#FBF8FF",
|
||||
100: "#F5F2FA",
|
||||
200: divider,
|
||||
300: "#EAE7EF",
|
||||
400: disabledBackground,
|
||||
500: "#DBD9E0",
|
||||
600: "#C7C5D0",
|
||||
700: disabled,
|
||||
800: textSecondary,
|
||||
900: textPrimary,
|
||||
},
|
||||
text: {
|
||||
primary: textPrimary,
|
||||
secondary: textSecondary,
|
||||
disabled,
|
||||
},
|
||||
divider,
|
||||
background: { default: background, paper: background },
|
||||
action: {
|
||||
hover: alpha(secondaryMain, 0.05),
|
||||
disabled: alpha(disabled, 0.6),
|
||||
disabledBackground: alpha(disabledBackground, 0.9),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function buildDarkPalette(accentColor: string): PaletteLike {
|
||||
const bg = "#0B0B0E";
|
||||
const paper = "#111116";
|
||||
const divider = alpha("#FFFFFF", 0.10);
|
||||
const textPrimary = "#EAEAF2";
|
||||
const textSecondary = alpha(textPrimary, 0.72);
|
||||
|
||||
const secondaryMain = "#A4A6C8";
|
||||
const disabled = alpha(textPrimary, 0.5);
|
||||
const disabledBackground = alpha("#FFFFFF", 0.08);
|
||||
|
||||
return {
|
||||
primary: buildPrimary(accentColor || "#606BDF"),
|
||||
secondary: {
|
||||
lighter: alpha(secondaryMain, 0.22),
|
||||
light: alpha(secondaryMain, 0.14),
|
||||
main: secondaryMain,
|
||||
dark: alpha(secondaryMain, 0.8),
|
||||
darker: alpha(secondaryMain, 0.95),
|
||||
},
|
||||
error: {
|
||||
lighter: alpha("#DE3730", 0.18),
|
||||
light: alpha("#DE3730", 0.12),
|
||||
main: "#FF5A52",
|
||||
dark: "#FF3B33",
|
||||
darker: "#FFC2BE",
|
||||
},
|
||||
warning: {
|
||||
lighter: alpha("#AE6600", 0.18),
|
||||
light: alpha("#AE6600", 0.12),
|
||||
main: "#FFB14A",
|
||||
dark: "#FF9A1F",
|
||||
darker: "#FFE1B8",
|
||||
},
|
||||
success: {
|
||||
lighter: alpha("#22892F", 0.18),
|
||||
light: alpha("#22892F", 0.12),
|
||||
main: "#4ADE80",
|
||||
dark: "#22C55E",
|
||||
darker: "#BBF7D0",
|
||||
},
|
||||
info: {
|
||||
lighter: alpha("#008394", 0.18),
|
||||
light: alpha("#008394", 0.12),
|
||||
main: "#22D3EE",
|
||||
dark: "#06B6D4",
|
||||
darker: "#BAF3FF",
|
||||
},
|
||||
grey: {
|
||||
50: bg,
|
||||
100: "#0F0F13",
|
||||
200: "#15151B",
|
||||
300: "#1C1C24",
|
||||
400: "#23232D",
|
||||
500: "#2D2D3A",
|
||||
600: "#3A3A4A",
|
||||
700: "#4A4A5D",
|
||||
800: "#B8B8C6",
|
||||
900: textPrimary,
|
||||
},
|
||||
text: {
|
||||
primary: textPrimary,
|
||||
secondary: textSecondary,
|
||||
disabled,
|
||||
},
|
||||
divider,
|
||||
background: { default: bg, paper },
|
||||
action: {
|
||||
hover: alpha("#FFFFFF", 0.06),
|
||||
disabled: alpha("#FFFFFF", 0.5),
|
||||
disabledBackground,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function buildCustomShadows(palette: any) {
|
||||
const shadowColor = palette.text.primary;
|
||||
const primaryColor = palette.primary.main;
|
||||
return {
|
||||
button: `0px 0.711px 1.422px 0px ${alpha(shadowColor, 0.05)}`,
|
||||
section: `0px 1px 2px 0px ${alpha(shadowColor, 0.07)}`,
|
||||
tooltip: `0px 12px 16px -4px ${alpha(shadowColor, 0.08)}, 0px 4px 6px -2px ${alpha(shadowColor, 0.03)}`,
|
||||
focus: `0px 0px 0px 3px ${alpha(primaryColor, 0.2)}`,
|
||||
};
|
||||
}
|
||||
|
||||
function buildTypography() {
|
||||
return {
|
||||
fontFamily: "'Archivo', system-ui, -apple-system, Segoe UI, Roboto, Helvetica Neue, Arial, sans-serif",
|
||||
letterSpacing: 0,
|
||||
h1: { fontWeight: 500, fontSize: 36, lineHeight: "40px" },
|
||||
h2: { fontWeight: 500, fontSize: 30, lineHeight: "34px" },
|
||||
h3: { fontWeight: 500, fontSize: 26, lineHeight: "30px" },
|
||||
h4: { fontWeight: 500, fontSize: 22, lineHeight: "26px" },
|
||||
h5: { fontWeight: 500, fontSize: 18, lineHeight: "22px" },
|
||||
h6: { fontWeight: 500, fontSize: 16, lineHeight: "20px" },
|
||||
subtitle1: { fontWeight: 500, fontSize: 14, lineHeight: "18px" },
|
||||
subtitle2: { fontWeight: 500, fontSize: 13, lineHeight: "17px" },
|
||||
body1: { fontWeight: 400, fontSize: 14, lineHeight: "18px" },
|
||||
body2: { fontWeight: 400, fontSize: 13, lineHeight: "17px" },
|
||||
caption: { fontWeight: 400, fontSize: 12, lineHeight: "16px", letterSpacing: 0 },
|
||||
overline: { fontWeight: 600, fontSize: 11, lineHeight: "14px", letterSpacing: "0.08em", textTransform: "uppercase" as const },
|
||||
// Saasable uses caption1; keep as a custom variant for internal usage if needed.
|
||||
caption1: { fontWeight: 500, fontSize: 12, lineHeight: "16px", letterSpacing: 0 },
|
||||
button: { textTransform: "capitalize" as const },
|
||||
};
|
||||
}
|
||||
|
||||
export const getTheme = (_mode: "light" | "dark", accentColor: string) => {
|
||||
const lightPalette = buildLightPalette(accentColor);
|
||||
const darkPalette = buildDarkPalette(accentColor);
|
||||
|
||||
const theme = createTheme({
|
||||
breakpoints: {
|
||||
values: {
|
||||
xs: 0,
|
||||
sm: 768,
|
||||
md: 1024,
|
||||
lg: 1266,
|
||||
xl: 1440,
|
||||
},
|
||||
},
|
||||
cssVariables: {
|
||||
cssVarPrefix: "",
|
||||
colorSchemeSelector: "data-color-scheme",
|
||||
},
|
||||
colorSchemes: {
|
||||
light: { palette: lightPalette, customShadows: buildCustomShadows(lightPalette) },
|
||||
dark: { palette: darkPalette, customShadows: buildCustomShadows(darkPalette) },
|
||||
},
|
||||
shape: { borderRadius: 8 },
|
||||
typography: buildTypography() as any,
|
||||
} as any) as any;
|
||||
|
||||
theme.components = {
|
||||
MuiCssBaseline: {
|
||||
styleOverrides: {
|
||||
body: {
|
||||
WebkitFontSmoothing: "antialiased",
|
||||
MozOsxFontSmoothing: "grayscale",
|
||||
},
|
||||
},
|
||||
},
|
||||
MuiPaper: {
|
||||
defaultProps: { elevation: 0 },
|
||||
styleOverrides: {
|
||||
root: ({ theme }: any) => ({
|
||||
border: `1px solid ${theme.vars.palette.divider}`,
|
||||
boxShadow: "none",
|
||||
backgroundImage: "none",
|
||||
}),
|
||||
},
|
||||
},
|
||||
MuiCard: {
|
||||
defaultProps: { elevation: 0 },
|
||||
styleOverrides: {
|
||||
root: ({ theme }: any) => ({
|
||||
border: `1px solid ${theme.vars.palette.divider}`,
|
||||
borderRadius: 12,
|
||||
backgroundImage: "none",
|
||||
boxShadow: theme.vars.customShadows.section,
|
||||
}),
|
||||
},
|
||||
},
|
||||
MuiButton: {
|
||||
defaultProps: { disableFocusRipple: true },
|
||||
styleOverrides: {
|
||||
root: ({ theme }: any) => ({
|
||||
borderRadius: 8,
|
||||
boxShadow: theme.vars.customShadows.button,
|
||||
"&:hover": { boxShadow: theme.vars.customShadows.button },
|
||||
}),
|
||||
},
|
||||
},
|
||||
MuiOutlinedInput: {
|
||||
defaultProps: { size: "small" },
|
||||
styleOverrides: {
|
||||
root: ({ theme }: any) => ({
|
||||
borderRadius: 8,
|
||||
boxShadow: theme.vars.customShadows.button,
|
||||
background: theme.vars.palette.background.default,
|
||||
paddingLeft: 10,
|
||||
paddingRight: 10,
|
||||
"&.Mui-disabled": {
|
||||
cursor: "not-allowed",
|
||||
input: { cursor: "not-allowed" },
|
||||
"& .MuiOutlinedInput-notchedOutline": { borderColor: theme.vars.palette.divider },
|
||||
},
|
||||
}),
|
||||
notchedOutline: ({ theme }: any) => ({ borderColor: theme.vars.palette.divider }),
|
||||
multiline: { padding: 10 },
|
||||
input: { paddingLeft: 0, paddingRight: 0 },
|
||||
},
|
||||
},
|
||||
MuiListItemButton: {
|
||||
styleOverrides: {
|
||||
root: ({ theme }: any) => ({
|
||||
borderRadius: 8,
|
||||
"&.Mui-selected": {
|
||||
backgroundColor: theme.vars.palette.action.hover,
|
||||
},
|
||||
}),
|
||||
},
|
||||
},
|
||||
MuiTableCell: {
|
||||
styleOverrides: {
|
||||
head: ({ theme }: any) => ({
|
||||
fontWeight: 600,
|
||||
color: theme.vars.palette.text.primary,
|
||||
background: theme.vars.palette.grey[100],
|
||||
}),
|
||||
root: {
|
||||
paddingTop: 10,
|
||||
paddingBottom: 10,
|
||||
},
|
||||
},
|
||||
},
|
||||
} as any;
|
||||
|
||||
return theme;
|
||||
};
|
||||
Reference in New Issue
Block a user