Hey guys, itās been a while since I last wrote in this amazing community, Iāve been pretty busy with family stuff and developing some complex projects, with and without Wappler.
But Iāve been reading here some very interesting topics that have helped me at times to solve some technical problems so I think itās always good to give back.
Dark mode is one of the most necessary features of the web. Many people prefer it because it is easy on the eyes.
In this tutorial you will learn how to use Wappler to detect when the system dark mode is enabled, and change the colors of the page accordingly without writing a single line of css and using bootstrap 5.3.0
Most modern browsers change their color scheme according to the operating system theme. This tutorial assumes that your browser falls into this category.
The demonstration will be using a switch and also a JS code that will allow us to match the mode that your system has active, whether your are using, windows or mac.
Step 1
It is necessary that you have the latest version of bootstrap, in this case 5.3.0 alpha 1, otherwise it will not work for you.
We can use the CDN:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384- GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous" />
Just copy and paste that into the head of your document.
An important point is that if you replace the bootstrap 5 link that wappler uses then wappler will not show in the app structure that bootstrap is installed, so I recommend pasting it after the link that wappler generates from bootstrap 5. Then you can remove the wappler bootstrap link in production.
Remember that version 5.3.0 is in alpha mode so use it at your own risk.
If you donāt want to use the CDN you can download the bootstrap files.
Step 2
Color mode styles are controlled by the data-bs-theme
attribute. This attribute can be applied to the <html>
element, or to any other element or Bootstrap component. If applied to the <html>
element, it will apply to everything. If applied to a component or element, it will be scoped to that specific component or element.
In this case I chose to put the code inside the body as follows:
<body is="dmx-app" id="darkmodetest" dmx-bind:data-bs-theme="input1.value">
The input1 has to do with our next step where we will create an on and off switch for our dark mode.
Step 3
Create a Custom Switch Form group. You can rename it as you like in this example we will leave the name as input1
Now we need to add the following attribute to the switch:
dmx-bind:value="checked.then('dark', 'light')"
Step 4
In order to detect if we are in dark mode or not we use window.matchMedia('(prefers-color-scheme: dark)').matches
This will return true if dark mode is enabled.
So I wrote a JS function using this information:
<script>
function setColorScheme() {
if (window.matchMedia &&
window.matchMedia('(prefers-color-scheme: dark)').matches) {
dmx.app.set('lightmode', "dark");
}
else {
dmx.app.set('lightmode', "light");
}
}
</script>
U can copy paste this code at the end of your body or put it in a JS file.
Step 5
We need to add a pageflow to our page so that it calls the function we just wrote:
<script is="dmx-flow" id="flow1" type="text/dmx-flow" autorun>{
runJS: {function: "setColorScheme", name: "setColorScheme"}
}</script>
Donāt forget to check the autorun!
Step 6
Finally we go back to our Switch and add the following attribute:
dmx-bind:checked="lightmode=='dark'"
So the page will go dark automatically when you load the site.
GrabacioĢn de pantalla 2022-12-26 a la(s) 23.38.00
And thatās how easy you can have dark mode in your web app with wappler.
Surely the Wappler team will incorporate this new feature in the future but since it is an alpha version of bootstrap, it may take months for it to be implemented so you can use it now .
BonusTrack
Here u have the entire code of my page in Wappler so u can play with it:
<!doctype html>
<html>
<head>
<meta name="ac:base" content="/test">
<base href="/test/">
<script src="dmxAppConnect/dmxAppConnect.js"></script>
<meta charset="UTF-8">
<title>divide</title>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js" integrity="sha256-CutOzxCRucUsn6C6TcEYsauvvYilEniTXldPa6/wu0k=" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="estilos2.css" />
<script src="dmxAppConnect/dmxImageParallax/dmxImageParallax.js" defer></script>
<link rel="stylesheet" href="https://unpkg.com/@fullcalendar/core@4.4.2/main.min.css" />
<script src="https://unpkg.com/@fullcalendar/core@4.4.2/main.min.js" defer></script>
<script src="https://unpkg.com/@fullcalendar/core@4.4.2/locales-all.min.js" defer></script>
<script src="https://unpkg.com/@fullcalendar/interaction@4.4.2/main.min.js" defer></script>
<script src="https://unpkg.com/@fullcalendar/daygrid@4.4.2/main.min.js" defer></script>
<script src="dmxAppConnect/dmxCalendar/dmxCalendar.js" defer></script>
<script src="https://unpkg.com/@fullcalendar/google-calendar@4.4.2/main.min.js" defer></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous" />
<script src="dmxAppConnect/dmxFormatter/dmxFormatter.js" defer></script>
</head>
<body is="dmx-app" id="dividescreen" dmx-bind:data-bs-theme="input1.value">
<script is="dmx-flow" id="flow1" type="text/dmx-flow" autorun>{
runJS: {function: "setColorScheme", name: "setColorScheme"}
}</script>
<dmx-value id="var1"></dmx-value>
<div class="container mt-3">
<div class="row justify-content-center text-uppercase">
<div class="col-4">
<div class="form-group mb-3">
<legend class="col-sm-2 col-form-label">One switch</legend>
<div class="form-check form-switch" style="">
<input class="form-check-input" type="checkbox" value="" id="input1" name="input1" dmx-bind:value="checked.then('dark', 'light')" dmx-bind:checked="lightmode=='dark'" style="height: 20px; width: 40px;">
<label class="form-check-label" for="input1"> Light switch </label>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col">
<h4 class="text-center">{{lightmode}} mode On</h4>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
<script>
function setColorScheme() {
if (window.matchMedia &&
window.matchMedia('(prefers-color-scheme: dark)').matches) {
dmx.app.set('lightmode', "dark");
}
else {
dmx.app.set('lightmode', "light");
}
}
</script>
</body>
</html>
Last updated: