Customization

Jumbo React Vite is designed for deep customisation. This page covers theme configuration, layout defaults, the four independent theme regions (main, header, sidebar, footer), and the runtime Customizer drawer.

Theme configuration

All theme assembly happens in src/config/index.ts. It calls createJumboTheme() from @jumbo/utilities/helpers with four separate MUI ThemeOptions objects — one per layout region:

typescript
// src/config/index.ts
import { createJumboTheme } from '@jumbo/utilities/helpers';
import { footerTheme } from '../themes/footer/default';
import { headerTheme } from '../themes/header/default';
import { mainTheme } from '../themes/main/default';
import { sidebarTheme } from '../themes/sidebar/default';
 
export const CONFIG = {
  THEME: createJumboTheme(mainTheme, headerTheme, sidebarTheme, footerTheme),
};

createJumboTheme() merges mainTheme as the base and overlays each region-specific theme on top, so you only need to define the overrides in headerTheme, sidebarTheme, and footerTheme.

Editing the main theme

The primary brand colours, typography, and component defaults are set in src/themes/main/default.ts:

typescript
// src/themes/main/default.ts (excerpt)
export const mainTheme = {
  palette: {
    mode: 'light',
    primary: {
      main: '#7352C7',    // Brand purple — change this to match your brand
      light: '#A07CDB',
      dark: '#4E2F9E',
      contrastText: '#FFF',
    },
    secondary: {
      main: '#E44F55',
    },
    background: {
      default: '#F5F7FA',
      paper: '#FFFFFF',
    },
  },
  typography: {
    fontFamily: 'NoirPro, Arial',
    h1: { fontSize: '1.5rem', fontWeight: 500 },
    h2: { fontSize: '1.25rem', fontWeight: 500 },
  },
  shape: {
    borderRadius: 8,
  },
};

Theme modes

Three pre-built modes are available. Each mode has corresponding files for all four regions:

ModeFile pathDescription
Light (default)src/themes/main/default.tsWhite background, brand purple primary
Semi-darksrc/themes/main/semi-dark.tsDark sidebar and header, light content area
Darksrc/themes/main/dark.tsFull dark palette across all regions

Switch modes at runtime using the Customizer drawer (see below), or change the default by swapping the imports in src/config/index.ts:

typescript
// To default to dark mode, swap the imports:
import { mainTheme } from '../themes/main/dark';
import { headerTheme } from '../themes/header/dark';
import { sidebarTheme } from '../themes/sidebar/dark';
import { footerTheme } from '../themes/footer/dark';

Layout configuration

The default layout configuration is defined in src/config/layouts/default.ts and consumed by StretchedLayout. Every property accepts values from the @jumbo/utilities/constants enums:

typescript
// src/config/layouts/default.ts
const defaultLayoutConfig: LayoutOptions = {
  sidebar: {
    open: true,
    hide: false,
    variant: SIDEBAR_VARIANTS.PERSISTENT,   // 'persistent' | 'temporary' | 'permanent'
    style: SIDEBAR_STYLES.FULL_HEIGHT,      // 'full-height' | 'clipped-under-header'
    view: SIDEBAR_VIEWS.FULL,               // 'full' | 'mini'
    scrollType: SIDEBAR_SCROLL_TYPES.FIXED,
    anchor: SIDEBAR_ANCHOR_POSITIONS.LEFT,  // 'left' | 'right' | 'top' | 'bottom'
    width: 240,
    minWidth: 80,
    drawerBreakpoint: 'xl',
  },
  header: {
    hide: false,
    fixed: true,
    sx: { height: 80 },
    drawerBreakpoint: 'xl',
  },
  footer: {
    hide: false,
  },
  content: {
    sx: { py: 4 },
  },
};

Layout config options

SectionKeyTypeDescription
sidebarvariantSIDEBAR_VARIANTSpersistent keeps sidebar mounted; temporary overlays it
sidebarviewSIDEBAR_VIEWSfull shows labels + icons; mini shows icons only
sidebarstyleSIDEBAR_STYLESfull-height extends sidebar above header; clipped-under-header sits below
sidebarwidthnumberExpanded sidebar width in pixels (default 240)
sidebarminWidthnumberCollapsed/mini sidebar width in pixels (default 80)
sidebardrawerBreakpointMUI BreakpointBelow this breakpoint, sidebar becomes a drawer overlay
headerfixedbooleanWhether the header sticks to the top on scroll
headersx.heightnumberHeader height in pixels (default 80)
footerhidebooleanSet true to remove the footer entirely

The Customizer drawer

The Customizer is a runtime settings panel that lets you switch themes, layout options, and locale without touching code. It appears as a floating button in the bottom-right corner of the app.

It is rendered by two components inside StretchedLayout:

tsx
// src/layouts/StretchedLayout/StretchedLayout.tsx (excerpt)
<JumboLayout header={<Header />} footer={<Footer />} sidebar={<Sidebar />}>
  <Outlet />
  <CustomizerSettings />   {/* Full settings drawer */}
  <CustomizerButton />     {/* Floating toggle button */}
</JumboLayout>

The Customizer persists sidebar state to a cookie (sidebar_state) so the chosen open/closed state survives page refreshes.

To change sidebar width globally, edit the values in src/config/layouts/default.ts:

typescript
sidebar: {
  width: 280,       // Expanded width — increase for wider labels
  minWidth: 64,     // Mini/collapsed width
}

These values drive the content margin calculations inside JumboLayoutProvider automatically.