123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597 |
- import { PaletteMode } from '@mui/material';
- import { Theme } from '@mui/material/styles';
- import { ButtonProps } from '@mui/material/Button';
- declare module '@mui/material/Typography' {
- interface TypographyPropsVariantOverrides {
- mono: true;
- }
- }
- declare module '@mui/material/styles' {
- interface TypeBackground {
- lightGrey?: string;
- grey?: string;
- light?: string;
- }
- interface Palette {
- background: TypeBackground;
- neutral: {
- 50: string;
- 100: string;
- 200: string;
- 300: string;
- 400: string;
- 500: string;
- 600: string;
- 700: string;
- 800: string;
- 900: string;
- };
- highlight: {
- light: string;
- dark: string;
- };
- }
- }
- const colors = {
- primary: {
- main: '#09B572',
- light: {
- light: '#f0fdf4',
- dark: '#1b4332',
- },
- dark: {
- light: '#07925E',
- dark: '#067A50',
- },
- },
- secondary: {
- main: '#1272CC',
- light: {
- light: '#E6F4FF',
- dark: '#003A8C',
- },
- dark: {
- light: '#0D5AA3',
- dark: '#0A4680',
- },
- },
- error: {
- main: '#D93C00',
- light: {
- light: '#FFEBE6',
- dark: '#7A1C00',
- },
- dark: {
- light: '#B33200',
- dark: '#8A2700',
- },
- },
- warning: {
- main: '#FF9800',
- light: {
- light: '#FFF4E5',
- dark: '#7A4A00',
- },
- dark: {
- light: '#E68A00',
- dark: '#B36B00',
- },
- },
- info: {
- main: '#2196F3',
- light: {
- light: '#E6F4FF',
- dark: '#0D3C61',
- },
- dark: {
- light: '#1A7BC9',
- dark: '#145FA0',
- },
- },
- success: {
- main: '#4CAF50',
- light: {
- light: '#E8F5E9',
- dark: '#1B5E20',
- },
- dark: {
- light: '#3D8B40',
- dark: '#2E7D32',
- },
- },
- neutral: {
- 50: '#F9FAFB',
- 100: '#F3F4F6',
- 200: '#E5E7EB',
- 300: '#D1D5DB',
- 400: '#9CA3AF',
- 500: '#6B7280',
- 600: '#4B5563',
- 700: '#374151',
- 800: '#1F2937',
- 900: '#111827',
- },
- background: {
- default: '#F3F4F6',
- paper: '#FFFFFF',
- },
- text: {
- primary: '#111827',
- secondary: '#4B5563',
- disabled: '#9CA3AF',
- },
- divider: '#E5E7EB',
- highlight: {
- light: '#FFE082',
- dark: '#003A8C',
- },
- };
- const spacing = (factor: number) => `${8 * factor}px`;
- const typography = {
- fontFamily: [
- 'Inter',
- '-apple-system',
- 'BlinkMacSystemFont',
- '"Segoe UI"',
- '"Helvetica Neue"',
- 'Arial',
- 'sans-serif',
- '"Apple Color Emoji"',
- '"Segoe UI Emoji"',
- '"Segoe UI Symbol"',
- ].join(','),
- h1: {
- fontSize: '36px',
- lineHeight: '42px',
- fontWeight: 'bold',
- letterSpacing: '-0.02em',
- },
- h2: {
- lineHeight: '24px',
- fontSize: '28px',
- fontWeight: 'bold',
- },
- h3: {
- lineHeight: '20px',
- fontSize: '24px',
- fontWeight: 'bold',
- },
- h4: {
- fontWeight: 500,
- lineHeight: '23px',
- fontSize: '20px',
- letterSpacing: '-0.02em',
- },
- h5: {
- fontWeight: 'bold',
- fontSize: '16px',
- lineHeight: '24px',
- },
- h6: {
- fontWeight: 'normal',
- fontSize: '16px',
- lineHeight: '24px',
- letterSpacing: '-0.01em',
- },
- body1: {
- fontSize: '14px',
- lineHeight: 1.5,
- },
- body2: {
- fontSize: '12px',
- lineHeight: '16px',
- },
- caption: {
- fontSize: '10px',
- lineHeight: '12px',
- },
- mono: {
- fontFamily: 'IBM Plex Mono, monospace',
- fontSize: 13,
- lineHeight: 1.8,
- },
- button: {
- textTransform: 'initial',
- lineHeight: '16px',
- fontWeight: '700',
- },
- };
- const getCommonThemes = (mode: PaletteMode) => ({
- typography,
- palette: {
- mode,
- primary: {
- main: colors.primary.main,
- light:
- mode === 'light'
- ? colors.primary.light.light
- : colors.primary.light.dark,
- dark:
- mode === 'light' ? colors.primary.dark.light : colors.primary.dark.dark,
- },
- secondary: {
- main: colors.secondary.main,
- light:
- mode === 'light'
- ? colors.secondary.light.light
- : colors.secondary.light.dark,
- dark:
- mode === 'light'
- ? colors.secondary.dark.light
- : colors.secondary.dark.dark,
- },
- error: {
- main: colors.error.main,
- light:
- mode === 'light' ? colors.error.light.light : colors.error.light.dark,
- dark: mode === 'light' ? colors.error.dark.light : colors.error.dark.dark,
- },
- warning: {
- main: colors.warning.main,
- light:
- mode === 'light'
- ? colors.warning.light.light
- : colors.warning.light.dark,
- dark:
- mode === 'light' ? colors.warning.dark.light : colors.warning.dark.dark,
- },
- info: {
- main: colors.info.main,
- light:
- mode === 'light' ? colors.info.light.light : colors.info.light.dark,
- dark: mode === 'light' ? colors.info.dark.light : colors.info.dark.dark,
- },
- success: {
- main: colors.success.main,
- light:
- mode === 'light'
- ? colors.success.light.light
- : colors.success.light.dark,
- dark:
- mode === 'light' ? colors.success.dark.light : colors.success.dark.dark,
- },
- neutral: colors.neutral,
- background: {
- default:
- mode === 'light' ? colors.background.default : colors.neutral[900],
- paper: mode === 'light' ? colors.background.paper : colors.neutral[800],
- grey: mode === 'light' ? colors.neutral[200] : colors.neutral[700],
- lightGrey: mode === 'light' ? colors.neutral[100] : colors.neutral[800],
- },
- text: {
- primary: mode === 'light' ? colors.text.primary : colors.neutral[50],
- secondary: mode === 'light' ? colors.text.secondary : colors.neutral[400],
- disabled: mode === 'light' ? colors.text.disabled : colors.neutral[600],
- },
- divider: mode === 'light' ? colors.divider : colors.neutral[700],
- highlight: {
- light: colors.highlight.light,
- dark: colors.highlight.dark,
- },
- },
- spacing,
- });
- export const getAttuTheme = (mode: PaletteMode) => {
- const commonThemes = getCommonThemes(mode);
- const isLight = mode === 'light';
- return {
- ...commonThemes,
- components: {
- MuiTypography: {
- styleOverrides: {
- ...typography,
- },
- },
- MuiButton: {
- defaultProps: {
- disableRipple: true,
- },
- styleOverrides: {
- root: ({
- theme,
- ownerState,
- }: {
- theme: Theme;
- ownerState: ButtonProps;
- }) => ({
- padding: theme.spacing(1, 3),
- textTransform: 'initial',
- fontWeight: 'bold',
- ...(ownerState.variant === 'text' && {
- padding: theme.spacing(1),
- color: theme.palette.primary.main,
- '&:hover': {
- backgroundColor: theme.palette.primary.main,
- color: theme.palette.background.paper,
- },
- }),
- ...(ownerState.variant === 'contained' && {
- boxShadow: 'none',
- '&:hover': {
- boxShadow: 'none',
- backgroundColor:
- ownerState.color === 'secondary'
- ? theme.palette.secondary.dark
- : theme.palette.primary.dark,
- },
- }),
- ...(ownerState.disabled && {
- pointerEvents: 'none',
- opacity: 0.6,
- }),
- }),
- },
- variants: [
- {
- props: { variant: 'contained', color: 'primary' },
- style: ({ theme }: { theme: Theme }) => ({
- backgroundColor: theme.palette.primary.main,
- color: theme.palette.background.paper,
- }),
- },
- {
- props: { variant: 'contained', color: 'secondary' },
- style: ({ theme }: { theme: Theme }) => ({
- backgroundColor: theme.palette.secondary.main,
- color: theme.palette.background.paper,
- }),
- },
- ],
- },
- MuiTab: {
- defaultProps: {
- disableRipple: true,
- },
- },
- MuiMenuItem: {
- defaultProps: {
- disableRipple: true,
- },
- styleOverrides: {
- root: {
- fontSize: '14px',
- padding: '8px 16px',
- minHeight: '36px',
- transition: 'background-color 0.2s ease',
- '&:hover': {
- backgroundColor: isLight
- ? 'rgba(10, 206, 130, 0.08)'
- : 'rgba(10, 206, 130, 0.16)',
- },
- '&.Mui-selected': {
- backgroundColor: isLight
- ? 'rgba(10, 206, 130, 0.16)'
- : 'rgba(10, 206, 130, 0.24)',
- '&:hover': {
- backgroundColor: isLight
- ? 'rgba(10, 206, 130, 0.24)'
- : 'rgba(10, 206, 130, 0.32)',
- },
- },
- '&.Mui-disabled': {
- opacity: 0.6,
- },
- '& .MuiListItemIcon-root': {
- color: isLight ? '#666' : '#aaa',
- minWidth: '36px',
- },
- },
- },
- },
- MuiDialog: {
- styleOverrides: {
- paper: {
- borderRadius: 8,
- boxShadow: '0px 5px 15px rgba(0, 0, 0, 0.15)',
- },
- },
- },
- MuiDialogActions: {
- styleOverrides: {
- spacing: {
- padding: spacing(4),
- },
- },
- },
- MuiDialogContent: {
- styleOverrides: {
- root: {
- padding: `${spacing(1)} ${spacing(4)}`,
- },
- },
- },
- MuiDialogTitle: {
- styleOverrides: {
- root: {
- padding: spacing(4),
- paddingBottom: spacing(1),
- },
- },
- },
- MuiFormHelperText: {
- styleOverrides: {
- contained: {
- marginLeft: 0,
- },
- },
- },
- MuiTextField: {
- styleOverrides: {
- root: {
- '& .MuiOutlinedInput-root': {
- '&:hover fieldset': {
- borderColor: isLight
- ? colors.primary.main
- : colors.primary.light.dark,
- },
- },
- },
- },
- },
- MuiFilledInput: {
- styleOverrides: {
- underline: {
- '&:before': {
- borderBottom: 'none',
- },
- borderWidth: 1,
- borderColor: 'transparent',
- },
- },
- },
- MuiInput: {
- styleOverrides: {
- underline: {
- '&:hover:not(.Mui-disabled):before': {
- borderWidth: 1,
- },
- borderWidth: 1,
- borderColor: 'transparent',
- },
- },
- },
- MuiChip: {
- styleOverrides: {
- root: {
- backgroundColor: isLight
- ? colors.primary.light.light
- : colors.primary.light.dark,
- color: isLight
- ? colors.primary.dark.light
- : colors.primary.light.light,
- '& .MuiChip-label': {
- fontWeight: 500,
- },
- },
- outlined: {
- borderColor: isLight
- ? colors.primary.main
- : colors.primary.light.dark,
- },
- clickable: {
- '&:hover': {
- backgroundColor: isLight
- ? colors.primary.light.light
- : colors.primary.dark.dark,
- },
- },
- deleteIcon: {
- color: isLight
- ? colors.primary.dark.light
- : colors.primary.light.light,
- '&:hover': {
- color: isLight
- ? colors.primary.dark.dark
- : colors.primary.light.dark,
- },
- },
- },
- },
- MuiTreeItem: {
- styleOverrides: {
- root: {
- fontSize: '15px',
- color: commonThemes.palette.primary.main,
- backgroundColor: commonThemes.palette.background.default,
- '& .MuiTreeItem-iconContainer': {
- width: 'auto',
- color: isLight ? '#666' : '#aaa',
- },
- '& .MuiTreeItem-group': {
- marginLeft: 0,
- '& .MuiTreeItem-content': {
- padding: '0 0 0 8px',
- },
- },
- '& .MuiTreeItem-label:hover': {
- backgroundColor: 'none',
- },
- '& .MuiTreeItem-content': {
- width: 'auto',
- padding: '0',
- '&.Mui-focused': {
- backgroundColor: isLight
- ? 'rgba(10, 206, 130, 0.08)'
- : 'rgba(10, 206, 130, 0.16)',
- },
- '&.Mui-selected': {
- backgroundColor: isLight
- ? 'rgba(10, 206, 130, 0.28)'
- : 'rgba(10, 206, 130, 0.36)',
- },
- '&.Mui-focused.Mui-selected': {
- backgroundColor: isLight
- ? 'rgba(10, 206, 130, 0.28) !important'
- : 'rgba(10, 206, 130, 0.36) !important',
- },
- '&:hover': {
- backgroundColor: isLight
- ? 'rgba(10, 206, 130, 0.08)'
- : 'rgba(10, 206, 130, 0.16)',
- },
- '& .MuiTreeItem-label': {
- background: 'none',
- },
- },
- },
- },
- },
- MuiMenu: {
- styleOverrides: {
- paper: {
- backgroundColor: commonThemes.palette.background.paper,
- boxShadow: '0px 5px 15px rgba(0, 0, 0, 0.15)',
- borderRadius: '8px',
- },
- list: {
- padding: '8px 0',
- },
- },
- },
- MuiSnackbar: {
- styleOverrides: {
- root: {
- '&.MuiSnackbar-anchorOriginTopCenter': {
- top: { xs: 56, md: 72 },
- },
- '&.MuiSnackbar-anchorOriginTopRight': {
- top: { xs: 56, md: 72 },
- right: (theme: Theme) => theme.spacing(1),
- },
- },
- },
- },
- MuiAlert: {
- styleOverrides: {
- root: {
- padding: '0 12px',
- borderRadius: '4px',
- display: 'flex',
- alignItems: 'center',
- color: '#fff',
- gap: '4px',
- '& .MuiAlert-action': {
- padding: '0',
- },
- '& .MuiAlert-icon': {
- marginRight: '4px',
- },
- '& svg': {
- fontSize: '16px',
- },
- },
- },
- },
- },
- };
- };
- export default getAttuTheme;
|