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:
// @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:
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:
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
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 }, }, };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 );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:
// src/themes/main/default.ts
export const mainTheme = {
direction: 'rtl',
// ...
};See the JumboRTL component docs for details on the Emotion cache setup.
Navbar color tokens
Sidebar nav item colors are defined via the jumboComponents.JumboNavbar extension on the sidebar
theme — these are separate from the main MUI palette:
// 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)',
},
},
},
};Before hardcoding a theme mode as the default, use the runtime Customizer drawer to verify that light, semi-dark, and dark modes all look correct. The Customizer is available on all layouts except SoloLayout.