Embrace the Shadows: Adding a Dark Mode Toggle in Laravel Jetstream

Embrace the Shadows: Adding a Dark Mode Toggle in Laravel Jetstream

Written by Brian on Jul 11th, 2023 Views Report Post

In the world of web development, one of the most sought-after features today is Dark Mode.

Dark Mode not only provides a visually appealing experience to users but also offers improved readability and reduced eye strain, especially in low-light environments. If you're a beginner like me, you might be wondering how to incorporate this highly desirable feature into your Laravel applications and especially in Jetstream. Fear not, for we shall explore the process of adding a Dark Mode toggle to your Laravel Jetstream project, where Batman himself would feel at home!

Step 1: Installing Laravel Jetstream

Before diving into the world of Dark Mode, let's ensure you have Laravel Jetstream installed in your project. Jetstream is a Laravel application starter kit that provides a robust foundation for building modern web applications. You can install Jetstream using Composer:

composer require laravel/jetstream

Step 2: Setting Up the Jetstream UI

Once Jetstream is installed, you need to set up its user interface scaffolding. Jetstream offers two options: Livewire and Inertia.js. Choose the option that best suits your project requirements. For the purpose of this tutorial, we'll assume you've selected Livewire.

To install Jetstream's Livewire UI, run the following command:

php artisan jetstream:install livewire

Step 3: Creating the Dark Mode Toggle

Next, add the x-data attribute to your top-level HTML element (like the tag) in your main layout file to declare a piece of reactive state:

<body x-data="themeSwitcher()" :class="{ 'dark': switchOn }">

themeSwitcher is a function we'll define in a moment, and isDark is a property of the object that function returns. This way, if isDark is true, the dark class will be applied to the element.

Step 4: Adding the function

In your app.js, define the themeSwitcher function in a script:

<script>
    window.themeSwitcher = function () {
        return {
            switchOn: JSON.parse(localStorage.getItem('isDark')) || false,
            switchTheme() {
                if (this.switchOn) {
                    document.documentElement.classList.add('dark')
                } else {
                    document.documentElement.classList.remove('dark')
                }
                localStorage.setItem('isDark', this.switchOn)
            }
        }
    }
</script>

This function returns an object that has isDark and toggleTheme properties. The isDark property gets its initial value from localStorage. If there's nothing in localStorage, it defaults to false. The toggleTheme function toggles the value of isDark and saves it to localStorage.

Step 5: The toggle

Now you can add a toggle button to switch themes. In this case, I have chosen to use a toggle from Pines (https://devdojo.com/pines) because it's awesome:

<div x-data="window.themeSwitcher()" x-init="switchTheme()" @keydown.window.tab="switchOn = false" class="flex items-center justify-center space-x-2">
    <input id="thisId" type="checkbox" name="switch" class="hidden" :checked="switchOn">

    <button 
        x-ref="switchButton"
        type="button" 
        @click="switchOn = ! switchOn; switchTheme()"
        :class="switchOn ? 'bg-blue-600' : 'bg-neutral-200'" 
        class="relative inline-flex h-6 py-0.5 ml-4 focus:outline-none rounded-full w-10">
        <span :class="switchOn ? 'translate-x-[18px]' : 'translate-x-0.5'" class="w-5 h-5 duration-200 ease-in-out bg-white rounded-full shadow-md"></span>
    </button>

    <label @click="$refs.switchButton.click(); $refs.switchButton.focus()" :id="$id('switch')" 
        :class="{ 'text-blue-600': switchOn, 'text-gray-400': ! switchOn }"
        class="text-sm select-none">
        Dark Mode
    </label>
</div>

You should also include Tailwind's dark mode variants in your tailwind.config.js file:

module.exports = {
  darkMode: 'class', // or 'media' if you want to use the OS setting
  // ...
}

And then, you'll have to use the dark: variant to style your elements for dark mode:

<div class="bg-white dark:bg-black text-black dark:text-white">
  <!-- Your content -->
</div>

Voila! Your Dark Mode toggle is now part of your Laravel Jetstream application.

Conclusion: Be like Batman and embrace a dark mode in your application. Your users will thank you for it and it is pretty awesome messing around with it.

Comments (0)