Dark mode for Rails 6

To enable dark mode using stimulus.js built in Rails 6
Icons/chart bar
Used 45 times
Created by
L Lucius Choi

Usage
If you use stimulus.js in Rails 6 project, you can implement easily dark mode using this template.
Notice: Most of codes in this template was referenced from dark-mode-switch plugin

Run this command in your Rails app directory in the terminal:

rails app:template LOCATION="https://railsbytes.com/script/x7ms44"
Template Source

Review the code before running this template on your machine.

run "touch app/javascript/controllers/dark_mode_controller.js"
inject_into_file 'app/javascript/controllers/dark_mode_controller.js', <<-JAVASCRIPT
import { Controller } from "stimulus";

function initTheme(darkSwitch) {
  const darkThemeSelected =
    localStorage.getItem("darkSwitch") !== null &&
    localStorage.getItem("darkSwitch") === "dark";
  darkSwitch.checked = darkThemeSelected;
  darkThemeSelected
    ? document.body.setAttribute("data-theme", "dark")
    : document.body.removeAttribute("data-theme");
}

function resetTheme(darkSwitch) {
  if (darkSwitch.checked) {
    document.body.setAttribute("data-theme", "dark");
    localStorage.setItem("darkSwitch", "dark");
  } else {
    document.body.removeAttribute("data-theme");
    localStorage.removeItem("darkSwitch");
  }
}

export default class extends Controller {
  static targets = [];

  connect() {
    console.log("Connected to DarkMode Controller...");
    const darkSwitch = document.getElementById("darkSwitch");
    if (darkSwitch) {
      initTheme(darkSwitch);
      darkSwitch.addEventListener("change", () => {
        resetTheme(darkSwitch);
      });
    }
  }
}
JAVASCRIPT

inject_into_file 'app/views/layouts/application.html.erb', after: "<body>" do
<<-HTML

    <div data-controller="dark-mode" class="custom-control custom-switch">
      <input type="checkbox" class="custom-control-input" id="darkSwitch" />
      <label class="custom-control-label" for="darkSwitch">Dark Mode</label>
    </div>
HTML
end

inject_into_file "app/assets/stylesheets/application.scss", "\n@import 'dark-mode';"

run "touch app/assets/stylesheets/dark-mode.css"
inject_into_file "app/assets/stylesheets/dark-mode.css", <<-CSS
[data-theme="dark"] {
  background-color: #111 !important;
  color: #eee;
}

[data-theme="dark"] .bg-light {
  background-color: #333 !important;
}

[data-theme="dark"] .bg-white {
  background-color: #000 !important;
}

[data-theme="dark"] .bg-black {
  background-color: #eee !important;
}
CSS
Comments
Willard
Tried this out in a jumpstart template and got an error. Still just playing around and haven't looked into it much yet.


 rails app:template LOCATION='https://railsbytes.com/script/x7ms44'
W, [2021-02-05T14:50:51.294821 #52458]  WARN -- Skylight: [SKYLIGHT] [4.3.2] Running Skylight in development mode. No data will be reported until you deploy your app.
(To disable this message for all local apps, run `skylight disable_dev_warning`.)
         run  touch app/javascript/controllers/dark_mode_controller.js from "."
File unchanged! The supplied flag value not found!  app/javascript/controllers/dark_mode_controller.js
File unchanged! The supplied flag value not found!  app/views/layouts/application.html.erb
rails aborted!
Thor::Error: The file /Users/admin/workspace/jumpstart/app/assets/stylesheets/application.scss does not appear to exist
/Users/admin/workspace/jumpstart/bin/rails:9:in `<top (required)>'
/Users/admin/workspace/jumpstart/bin/spring:15:in `<top (required)>'
Tasks: TOP => app:template