ionic-team / ionic-docs

https://ionicframework.com/docs
Apache License 2.0
589 stars 3.02k forks source link

bug: Unexpected dark mode behavior in v5 start app. Contains potential fix. #1295

Closed santekotturi closed 7 months ago

santekotturi commented 4 years ago

Bug Report

Ionic version:

[] 4.x [X] 5.x

Current behavior:

Using the v5 starter app (in my case sidemenu), the dark mode scss styles exist to automatically change the app to dark mode based on the system preference of the user's computer. The documentation around Dark Mode is misleading because of some very small nuances in code.

Expected behavior:

I don't expect the entire app to change it's core styles unexpectedly. I developed an app during the day time, then randomly tested at night and was amazed to see the entire thing had changed. Perhaps this would be expected if a "dark-mode" starter existed. I've been using ionic since alpha days and I don't find too many blatant easter eggs!

How this relates to the docs: the docs all include the "dark" css class being applied to the body but the default variables.scss that comes with the starter does NOT include this.

Steps to reproduce:

Start a sidemenu app using ionic cli. On a macbook, turn your dark mode on/off in system preferences. The app automatically changes and there's no apparent way to stop or change this.

Related code: in variables.scss, remove the media query for @media (prefers-color-scheme: dark) then add .dark to all body rules i.e. body.dark and .ios body.dark

add the following to app.component.ts:

  ngOnInit() {
    const path = window.location.pathname.split('folder/')[1];
    if (path !== undefined) {
      this.selectedIndex = this.appPages.findIndex(
        page => page.title.toLowerCase() === path.toLowerCase()
      );
    }

    const osDarkness = window.matchMedia('(prefers-color-scheme: dark)');
    // check the initial state
    this.applyDarkness(osDarkness);
    // add listener
    osDarkness.addListener(e => {
      this.applyDarkness(e);
    });
  }

  applyDarkness(matchMediaEvent) {
    if (matchMediaEvent.matches) {
      this.darkMode = true;
      document.body.classList.toggle('dark', true);
    } else {
      this.darkMode = false;
      document.body.classList.toggle('dark', false);
    }
    // this is needed to update the ngModel of the ion-toggle
    // to avoid the toggle state to become backwards
    this.ref.detectChanges();
  }

  toggleDarkness() {
    // this.darkMode = !this.darkMode;
    if (this.darkMode) {
      document.body.classList.toggle('dark', true);
    } else {
      document.body.classList.toggle('dark', false);
    }
  }

also make sure you import import { ChangeDetectorRef, Component, OnInit } from '@angular/core';

finally, in app.component.html add:

        <ion-item>
          <ion-label>Dark Mode</ion-label>
          <ion-toggle
            (ionChange)="toggleDarkness()"
            [(ngModel)]="darkMode"
          ></ion-toggle>
        </ion-item>
insert short code snippets here

Other information:

Ionic info:

Ionic:

   Ionic CLI                     : 6.2.0 (/Users/santekotturi/.nvm/versions/node/v12.16.1/lib/node_modules/@ionic/cli)
   Ionic Framework               : @ionic/angular 5.0.5
   @angular-devkit/build-angular : 0.803.25
   @angular-devkit/schematics    : 8.3.25
   @angular/cli                  : 8.3.25
   @ionic/angular-toolkit        : 2.2.0

Utility:

   cordova-res : not installed
   native-run  : not installed

System:

   NodeJS : v12.16.1 (/Users/santekotturi/.nvm/versions/node/v12.16.1/bin/node)
   npm    : 6.13.4
   OS     : macOS Catalina
liamdebeasi commented 4 years ago

Thanks for the issue. We probably need to update our documentation guidance on this. You can remove the dark mode code in themes/variables.scss. Native iOS apps are expected to work with dark mode as of iOS 13, so we added the automatic switching in order to keep with that guidance. But I agree, it can be a bit jarring if you are not expecting it.

edit: I am going to move this to the Ionic Docs repo. Thanks!

liamdebeasi commented 7 months ago

Hey there,

With the Ionic 8 release we revamped our dark mode documentation to provide more clarification around when dark mode gets applied.