darkmodetoggle
Reactive icon

DarkModeToggle

Stable version 1.0.0 (Compatible with OutSystems 11)
Uploaded
 on 22 Sep (20 hours ago)
 by 
2.0
 (1 rating)
darkmodetoggle

DarkModeToggle

Documentation
1.0.0

Dark Mode Toggle — OutSystems Forge Documentation


📋 Table of Contents

  1. Overview & Description
  2. Installation Guide
  3. Component Properties Reference
  4. Usage Examples
  5. Troubleshooting Guide

1. Overview & Description <a name="overview"></a>

What is Dark Mode Toggle?

Dark Mode Toggle is a lightweight, fully client-side Reactive Web Block for OutSystems that provides an instant dark/light mode switcher for any Reactive Web application. It applies theme colors globally across the entire app using CSS variables, remembers the user's preference in localStorage, and supports automatic detection of the system's dark/light preference.

No external libraries required — built entirely with vanilla JavaScript and OutSystems Reactive Web.

Key Features

  • ✅ Instant dark/light mode switching with smooth transition
  • ✅ 3 display styles — Toggle Switch, Sun/Moon Icon, or Both
  • ✅ 4 built-in preset themes — Default, Sunset, Ocean, Forest
  • ✅ Auto mode — follows OS/system dark/light preference
  • ✅ Remembers user preference via localStorage
  • ✅ Applies globally to entire app via CSS variables
  • ✅ Smooth color transition animation
  • ✅ Fires OutSystems event to parent on mode change
  • ✅ Force set mode via SetDarkMode action
  • ✅ Get current mode via GetCurrentMode action
  • ✅ Best placed in Layout Block — works across all screens
  • ✅ No external libraries or CDN required
  • ✅ Mobile compatible

Supported Platforms

PlatformSupported
Reactive Web✅ Yes
Mobile App✅ Yes
Traditional Web❌ No
OutSystems Developer Cloud (ODC)⚠️ Not tested

Dependencies

DependencyVersion
OutSystems PlatformO11
External JS LibrariesNone

Built-in Preset Themes

ThemeLight BGDark BGAccent
Default#ffffff#1a1a2e#0057D9
Sunset#fff8f0#2d1b00#ff6b35
Ocean#f0f8ff#001428#00b4d8
Forest#f0fff4#0d2818#2d6a4f

2. Installation Guide <a name="installation"></a>

Step 1 — Download from Forge

  1. Go to OutSystems Forge
  2. Search for Dark Mode Toggle
  3. Click Install → Select your environment
  4. Wait for installation to complete

Step 2 — Add Reference in Your Module

  1. Open your module in Service Studio
  2. Go to Manage Dependencies (Ctrl+Q)
  3. Search for DarkModeLib
  4. Select and add:
ElementType
DarkModeToggleWeb Block
DarkModeConfigStructure
ToggleDarkModeClient Action
GetCurrentModeClient Action
SetDarkModeClient Action
  1. Click Apply

Step 3 — Add to Layout Block (Recommended)

Placing the toggle in your Layout Block makes it available on every screen automatically — this is the recommended approach.

  1. Open your Layout Web Block (usually LayoutTopMenu or LayoutSideMenu)
  2. Add Local Variables:
VariableData TypeDefault
DMConfigDarkModeConfig
CurrentModeText"Light"
  1. In Layout's On Initialize event add Assign:
DMConfig.Style              = "Both"
DMConfig.DefaultMode        = "Auto"
DMConfig.Theme              = "Default"
DMConfig.RememberPreference = True
DMConfig.TransitionSpeed    = 300
  1. Drag DarkModeToggle block into the right side of your menu header
  2. Set Config = DMConfig

Step 4 — Wire the Event

  1. Click the DarkModeToggle block
  2. Find OnModeChanged event in properties
  3. Set to New Client Action → name it ModeChanged
  4. Inside ModeChanged add Assign:
CurrentMode = Mode

Step 5 — Add CSS Variables to Your App Stylesheet

Add these to your main application stylesheet to ensure dark mode overrides OutSystems default styles:

body {
    background-color: var(--dm-bg) !important;
    color: var(--dm-text) !important;
}

.app-content, .main-content,
[class*="layout"] {
    background-color: var(--dm-bg) !important;
    color: var(--dm-text) !important;
}

input, textarea, select, .form-control {
    background-color: var(--dm-surface) !important;
    color: var(--dm-text) !important;
    border-color: var(--dm-border) !important;
}

Step 6 — Use CSS Variables in Your Screens

In your screen containers and cards use CSS variables for colors:

/* Example card */
.my-card {
    background-color: var(--dm-surface);
    color: var(--dm-text);
    border: 1px solid var(--dm-border);
}

Step 7 — Publish and Test

  1. Press Ctrl+P to publish
  2. Open app in browser
  3. Toggle should appear in menu and switch modes instantly

3. Component Properties Reference <a name="properties"></a>

Web Block: DarkModeToggle

PropertyTypeMandatoryDescription
ConfigDarkModeConfigYesMain configuration structure

Events: DarkModeToggle

EventParameterTypeDescription
OnModeChangedModeTextFires when mode is toggled — returns "Light" or "Dark"

Structure: DarkModeConfig

AttributeTypeDefaultDescription
StyleText"Toggle"Display style — Toggle / Icon / Both
DefaultModeText"Auto"Starting mode — Light / Dark / Auto
ThemeText"Default"Color theme — Default / Sunset / Ocean / Forest
RememberPreferenceBooleanTrueSave user preference to localStorage
TransitionSpeedInteger300Color transition speed in milliseconds

Style Values

ValueDescription
ToggleShows animated toggle switch only
IconShows ☀️/🌙 icon button only
BothShows both toggle switch and icon

DefaultMode Values

ValueDescription
LightAlways starts in light mode
DarkAlways starts in dark mode
AutoFollows OS/system dark/light preference

Client Actions

ToggleDarkMode

Switches between dark and light mode programmatically.

ParameterDirectionTypeDescription
NewModeOutputTextThe mode after toggle — "Light" or "Dark"

GetCurrentMode

Returns the currently active mode.

ParameterDirectionTypeDescription
CurrentModeOutputTextCurrent mode — "Light" or "Dark"

SetDarkMode

Forces a specific mode — useful for programmatic control.

ParameterDirectionTypeDescription
ModeInputTextMode to set — "Light" or "Dark"

CSS Variables Reference

These variables are set globally and available in any screen stylesheet:

VariableLight ValueDark ValueUsage
--dm-bg#ffffff#1a1a2ePage/body background
--dm-text#333333#ffffffText color
--dm-surface#f5f5f5#16213eCards, panels, inputs
--dm-border#e0e0e0#0f3460Borders, dividers
--dm-accent#0057D9#0057D9Buttons, links, highlights

4. Usage Examples <a name="usage"></a>

Example 1 — Basic Setup in Layout (Recommended)

Layout Block — On Initialize
  └── Assign:
        DMConfig.Style              = "Both"
        DMConfig.DefaultMode        = "Auto"
        DMConfig.Theme              = "Default"
        DMConfig.RememberPreference = True
        DMConfig.TransitionSpeed    = 300

Layout Block — Header Menu (Right Side)
  └── DarkModeToggle
        ├── Config        = DMConfig
        └── OnModeChanged → ModeChanged action
              └── Assign: CurrentMode = Mode

Example 2 — Toggle Switch Only Style

DMConfig.Style       = "Toggle"
DMConfig.DefaultMode = "Light"
DMConfig.Theme       = "Default"

Shows only the animated toggle switch — clean and minimal.


Example 3 — Icon Only Style

DMConfig.Style       = "Icon"
DMConfig.DefaultMode = "Auto"
DMConfig.Theme       = "Ocean"

Shows only ☀️ in light mode and 🌙 in dark mode — great for compact menus.


Example 4 — Always Start in Dark Mode

DMConfig.DefaultMode        = "Dark"
DMConfig.RememberPreference = False

App always starts in dark mode and does not remember user changes.


Example 5 — Force Dark Mode from a Button

Dark Mode Button → OnClick
  └── SetDarkMode
        └── Mode = "Dark"

Programmatically force dark mode from anywhere in your app.


Example 6 — Check Current Mode and Act on It

Some Action
  ├── GetCurrentMode
  │     └── Output: CurrentMode
  │
  └── If CurrentMode = "Dark"
        └── Do something for dark mode
  └── If CurrentMode = "Light"
        └── Do something for light mode

Example 7 — Use CSS Variables in Your Screen

In any screen's container or card style property:

/* Apply to any container */
background-color: var(--dm-surface);
color: var(--dm-text);
border: 1px solid var(--dm-border);
border-radius: 8px;
padding: 16px;

This automatically switches colors when dark mode is toggled — no extra code needed.


Example 8 — Different Theme per User Role

On Initialize
  ├── If CurrentUser.IsAdmin
  │     └── Assign: DMConfig.Theme = "Ocean"
  │
  └── If Not CurrentUser.IsAdmin
        └── Assign: DMConfig.Theme = "Default"

5. Troubleshooting Guide <a name="troubleshooting"></a>

❌ Issue: Dark Mode Not Applying to Some Elements

Cause: Those elements use hardcoded colors instead of CSS variables.

Fix:Replace hardcoded colors in your stylesheets with CSS variables:

/* Before */
background-color: #ffffff;
color: #333333;

/* After */
background-color: var(--dm-bg);
color: var(--dm-text);

❌ Issue: OutSystems Default Styles Overriding Dark Mode

Cause: OutSystems platform CSS has higher specificity.

Fix:Add !important to your app stylesheet:

body {
    background-color: var(--dm-bg) !important;
    color: var(--dm-text) !important;
}

❌ Issue: Preference Not Remembered After Page Refresh

Cause: RememberPreference is set to False or localStorage is blocked.

Fix:

  1. Set DMConfig.RememberPreference = True
  2. Check if browser allows localStorage:
console.log(localStorage.getItem("dm_preference"));

Should return "Dark" or "Light" — if null, localStorage is blocked.


❌ Issue: Auto Mode Not Working

Cause: Browser does not support prefers-color-scheme media query.

Fix:This is a browser limitation. Set a specific DefaultMode as fallback:

DMConfig.DefaultMode = "Light"

Modern browsers (Chrome, Firefox, Safari, Edge) all support prefers-color-scheme.


❌ Issue: Toggle Animation Not Smooth

Cause: TransitionSpeed set too low or CSS transition being overridden.

Fix:

  1. Set DMConfig.TransitionSpeed = 300 (recommended)
  2. Make sure no other CSS is overriding transitions on * selector

❌ Issue: OnModeChanged Event Not Firing

Cause: Event not wired correctly on the block.

Fix:

  1. Click DarkModeToggle block on screen
  2. Find OnModeChanged in properties panel
  3. Make sure it points to a Client Action
  4. Verify the action has Mode as input parameter

❌ Issue: Toggle Visible on Some Screens but Not Others

Cause: Toggle placed on individual screen instead of Layout Block.

Fix:Move the DarkModeToggle block to your Layout Web Block so it appears on every screen automatically. See Installation Guide Step 3.


❌ Issue: Colors Flash Briefly on Page Load Before Dark Mode Applies

Cause: Dark mode is applied after the page renders (On After Render).

Fix:Add this inline style to your app's index.html or layout's header to prevent flash:

// Add JS node in Layout's On Initialize (before On After Render)
var saved = localStorage.getItem("dm_preference");
if (saved === "Dark") {
    document.documentElement.setAttribute("data-theme", "dark");
    document.body.style.backgroundColor = "#1a1a2e";
}

💡 General Tips

  • Always place the toggle in the Layout Block — not individual screens
  • Use DefaultMode = "Auto" for the best user experience — respects OS preference
  • Use var(--dm-surface) for cards and panels — not var(--dm-bg)
  • Use var(--dm-accent) for buttons and interactive elements
  • Test all 4 themes before submitting to Forge — take screenshots of each
  • TransitionSpeed = 0 disables animation — useful for testing

Documentation Version: 1.0.0 
Component Version: 1.0.0 
Last Updated: 2026 
Author: Vinayak Siddhiwal.