Theming

Jumbo React Vite extends MUI's standard ThemeProvider with an independent sub-theme for each layout region. This lets you style the header, sidebar, and footer with completely different palettes from the main content area — including dark sidebars with a light content region (semi-dark mode).

Theme architecture

JumboTheme creates four independent ThemeProvider contexts stacked inside one another:

JumboTheme (main content theme)
  └── JumboThemeHeader   (header region theme)
  └── JumboThemeSidebar  (sidebar region theme)
  └── JumboThemeFooter   (footer region theme)

Components inside each region automatically consume the correct theme. The createJumboTheme() utility assembles the four ThemeOptions objects into a JumboThemeConfig:

typescript
// @jumbo/utilities/helpers.ts
export const createJumboTheme = (
  mainTheme, headerTheme, sidebarTheme, footerTheme
): JumboThemeConfig => ({
  main:    mainTheme,
  header:  { ...mainTheme, ...headerTheme  },
  sidebar: { ...mainTheme, ...sidebarTheme },
  footer:  { ...mainTheme, ...footerTheme  },
});

Each region inherits all keys from mainTheme and then overrides with its region-specific values.

Theme mode files

Three mode variants are pre-built for each region:

src/themes/
  main/     default.ts    semi-dark.ts    dark.ts
  header/   default.ts    semi-dark.ts    dark.ts
  sidebar/  default.ts    semi-dark.ts    dark.ts
  footer/   default.ts    semi-dark.ts    dark.ts

The type field on each theme object identifies the mode and is read by the JumboTheme provider to apply mode-specific internal styles:

typescript
export const mainTheme = {
  type: 'light',   // 'light' | 'semi-dark' | 'dark'
  palette: { mode: 'light', ... },
};

Switching themes at runtime

The CustomizerSettings drawer calls the sub-theme hooks to swap all four regions simultaneously:

typescript
import { useJumboTheme }        from '@jumbo/components/JumboTheme';
import { useJumboThemeHeader }  from '@jumbo/components/JumboTheme';
import { useJumboThemeSidebar } from '@jumbo/components/JumboTheme';
import { useJumboThemeFooter }  from '@jumbo/components/JumboTheme';
import { mainTheme as darkMain }    from '@/themes/main/dark';
import { headerTheme as darkHeader } from '@/themes/header/dark';
 
export function ThemeModeToggle() {
  const { setTheme: setMain }     = useJumboTheme();
  const { setTheme: setHeader }   = useJumboThemeHeader();
  const { setTheme: setSidebar }  = useJumboThemeSidebar();
  const { setTheme: setFooter }   = useJumboThemeFooter();
 
  const enableDarkMode = () => {
    setMain(darkMain);
    setHeader(darkHeader);
    setSidebar(darkSidebar);
    setFooter(darkFooter);
  };
 
  return <Button onClick={enableDarkMode}>Dark mode</Button>;
}

Creating a custom theme preset

  1. Create theme files for each region

    typescript
    // src/themes/main/brand.ts
    export const mainTheme = {
      type: 'light' as const,
      palette: {
        mode: 'light',
        primary: { main: '#1A73E8', light: '#4CA6FF', dark: '#0050B3' },
        secondary: { main: '#F44336' },
        background: { default: '#F8F9FA', paper: '#FFFFFF' },
      },
      typography: {
        fontFamily: 'Inter, system-ui, sans-serif',
        h1: { fontWeight: 700 },
      },
    };
  2. Assemble with createJumboTheme

    typescript
    // src/config/brand.ts
    import { createJumboTheme } from '@jumbo/utilities/helpers';
    import { mainTheme }    from '../themes/main/brand';
    import { headerTheme }  from '../themes/header/default';
    import { sidebarTheme } from '../themes/sidebar/default';
    import { footerTheme }  from '../themes/footer/default';
     
    export const BRAND_THEME = createJumboTheme(
      mainTheme, headerTheme, sidebarTheme, footerTheme
    );
  3. Apply via JumboTheme

    typescript
    // src/config/index.ts — swap CONFIG.THEME to use your brand theme
    import { BRAND_THEME } from './brand';
    export const CONFIG = { THEME: BRAND_THEME };

RTL support

JumboRTL (inside App.tsx) automatically flips all CSS directional properties when theme.direction === 'rtl'. Enable RTL by setting direction on the main theme:

typescript
// src/themes/main/default.ts
export const mainTheme = {
  direction: 'rtl',
  // ...
};

See the JumboRTL component docs for details on the Emotion cache setup.

Sidebar nav item colors are defined via the jumboComponents.JumboNavbar extension on the sidebar theme — these are separate from the main MUI palette:

typescript
// src/themes/sidebar/default.ts
export const sidebarTheme = {
  jumboComponents: {
    JumboNavbar: {
      colors: {
        nav: 'rgba(255,255,255,0.7)',
        navHover: '#FFFFFF',
        navActive: '#7352C7',
        subMenuColor: 'rgba(255,255,255,0.6)',
        subMenuHoverBg: 'rgba(255,255,255,0.08)',
        subMenuActiveBg: 'rgba(115,82,199,0.2)',
      },
    },
  },
};