Code Monkey home page Code Monkey logo

googlechromelabs / dark-mode-toggle Goto Github PK

View Code? Open in Web Editor NEW
1.2K 17.0 72.0 1.39 MB

A custom element that allows you to easily put a Dark Mode πŸŒ’ toggle or switch on your site:

Home Page: https://googlechromelabs.github.io/dark-mode-toggle/demo/index.html

License: Apache License 2.0

JavaScript 80.74% Smarty 19.26%
dark-mode dark-theme dark-mode-switcher dark-mode-toggle dark-theme-switcher dark-theme-toggle prefers-color-scheme web-components custom-elements custom-elements-v1

dark-mode-toggle's Issues

Any way to toggle light/dark native widgets when using <meta name='color-scheme' content='light dark'> ?

I added to my page so that the browser would draw dark scrollbars and other native widgets in dark mode. When I have the browser in dark mode and use the dark-mode-toggle switch to change my website to light mode, the widgets stay in dark mode. And vice versa... with browser in light mode and website toggled to dark mode, browser continues using light widgets. Is there any way to also toggle the meta tag so that native widgets follow the current theme? Not sure if it's possible but thought I would ask. Light widgets look OK in dark mode, but dark widgets look bad in light mode, so for now I removed the meta line to force light widgets.

Extra unnecessary right margin

When not setting a legend on the component there is still a right margin relative to the icon, see the following screenshot:

image

When no legends are set should not the icon be centred with no extra unnecessary margin?

EDIT: Also, why is the fieldset so wide compared to the icon, could we make the fieldset the same area than the icon or add a CSS vars to customise the fieldset? My goal here would be to set the width and height of the fieldset to 32px to match the other icons contained within mwc-button-icon.

image

Keep light mode after changing page for Wordpress Theme

I noticed that if the person is in light mode and switches to dark mode and refreshes the page it continues in dark mode, now if the person is in dark mode and switches to light and refreshes the page it does not work page back for dark.

I use a select button

image

Can you help me?

// Get current theme
var theme = localStorage.getItem( 'theme' );
// Set defaults if theme is not defined.
if ( ! theme ) {
  localStorage.setItem( 'theme', 'light' );
  theme = 'light';
}
// Add theme to the body.
document.body.classList.add( theme );

// Handle onClick events
document.getElementById( 'theme-toggle' ).addEventListener( 'click', () => {
  // Cleanup classes from body.
  document.body.classList.remove( 'light' );
  document.body.classList.remove( 'dark' );
  // Change the theme.
  theme = ( theme === 'light' ) ? 'dark' : 'light';
  // Save the theme.
  localStorage.setItem( 'theme', theme );
  // Apply the theme.
  document.body.classList.add( theme );
});

if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
	document.body.classList.remove( 'light' );
	document.body.classList.remove( 'dark' );
    var theme = 'dark';
	localStorage.setItem( 'theme', theme );
	document.body.classList.add( theme );
}
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => {
	document.body.classList.remove( 'light' );
	document.body.classList.remove( 'dark' );
    var newColorScheme = event.matches ? "dark" : "light";
	localStorage.setItem( 'theme', newColorScheme );
	document.body.classList.add( newColorScheme );
});

Files are .mjs, but seem to be hand-written UMD

Is there a reason to do UMD style at all? A module defined a scope, so you don't need a function scope to keep from accidentally creating globals. If you did, you could just use a block {} anyway.

Also, both the source file and dist file have .mjs extensions even though neither has an import or export. Is there a reason to check-in the minified file? It can be published to npm and available via unpkg.com without being checked in.

dark-mode-toggle with React

Hi,

A DOMException error occurs when <dark-mode-toggle> is used in React apps.

Failed to construct 'CustomElement': The result must not have attributes

I think it occurs when document.createElement has been called.

The error would be solved if the DOM related tasks move from constructor to connectedCallback, but I am not sure this is an appropriate change for dark-mode-toggle.

Implement saving light/dark mode

Hello, could you tell me how can I implement saving light/dark mode on my site like here (https://v8.dev/) without "Remember" checkbox? Adding "permanent" parameter doesn't help. Though this parameter is set in this website code and theme is saved without the checkbox.

Add aria-label for lighthouse

When running the Chrome lighthouse, I am getting the following accessibility issue:

image

image

Could you please easer hard code an aria-label value or pass it down as a property?

dark-mode-toggle and SVG

we've experimented with your AMP variation. our planned site heavily uses SVG (rather than PNG/JPG). the dark-mode 'bleeds' thru the SVGs. we have a sample to share if you would like to see this use case. we would be willing to change our approach to using SVG linearGradient and radialGradient to work with dark-mode-toggle, but are uncertain how to do so. let me know if you are willing to collaborate with us on supporting SVGs and dark-mode-toggle.
/jay gray

Declare as a Web Component

Hi GoogleChromeLabs,

I am no expert in web dev or web components, but in my current project when using the dark-mode-toggle, lit-plugin is throwing the following warning message:

Unknown tag <dark-mode-toggle>.
  Check that you've imported the element, and that it's declared on the HTMLElementTagNameMap. If it can't be imported, consider adding it to the 'globalTags' plugin configuration or disabling the 'no-unknown-tag' rule.lit-plugin(no-unknown-tag-name)(2322)

Is there anything you could do to fix the above?

Kind regards,
Alex

CSS custom property to change the icon size

Hey @tomayac , thank you for this custom element! I've started using it on a remake on my site and I really like it, it's been fun and easy to use! πŸŽ‰

I'm just wondering if there's a way to change the size of the icons? I see that there are CSS custom properties to change the font size of the labels, but I couldn't find one for the icons (please correct me if I'm wrong, I might have just missed it πŸ˜… ).

I see from dark-mode-toggle.js#L127-130 that the icons have a size of 1rem, maybe a --dark-mode-toggle-icon-size custom property to customize this value?

Thanks! πŸ˜„

Support for using as a React component

Thanks for this awesome little widget, I've looked at quite a few dark mode toggles and I like the "switch" version of this one the most so far!

I would like to use it as a React component, so I'd like to ask if submitting such an abstraction layer over the current web component would be accepted here as a PR, or in case not, whether you'd be happy with me creating a separate wrapper package for it?

(I'd also like to include slider.css, moon.svg and sun.svg, but they aren't accessible from simply linking this package as a dependency, so in that case I would copy them and do my best to annotate them properly according to the Apache-2.0 license of this repo.)

A few issues

I have followed and read your tutorial at https://web.dev/prefers-color-scheme/ with great interest. It is a really nice tutorial for newbie like me, so many thanks for that.

Also, I decided to go the lazy/easy route and simply use your component rather than implementing all the logic behind for the theme switch.

My application is based on material web components - https://github.com/material-components/material-components-web-components - and style wise it does not really blend in, see the following screenshot:

image

As you can see my language button got a ripple around it, it is in fact a button when your component is just an icon, you can also see that the size is different, I have tried to see if I could wrap your component around a mwc-icon-button but I did not manage to get it to work.

This is the code that I have so far:

    <mwc-top-app-bar-fixed
            @MDCTopAppBar:nav=${() => (this.drawer.open = !this.drawer.open)}
          >
            <mwc-icon-button
              slot="navigationIcon"
              icon="menu"
              id="hamburger"
            ></mwc-icon-button>
            <h3 slot="title">Evil Corp</h3>
            <mwc-icon-button
              slot="actionItems"
              icon="languages"
            ></mwc-icon-button>
            <dark-mode-toggle
              slot="actionItems"
              appearance="toggle"
              permanent
            ></dark-mode-toggle>
            <!-- <mwc-icon-button-toggle
              onIcon="nights_stay"
              offIcon="wb_sunny"
              slot="actionItems"
            ></mwc-icon-button-toggle> -->
            <div class="navbar">
              <nav class="flex-container">
                <my-menu class="navbar-nav"></my-menu>
              </nav>
              <mwc-linear-progress></mwc-linear-progress>
            </div>
      </mwc-top-app-bar-fixed>

Also,I have notice that when my preferred theme is dark and I set the component to remember the choice when I visit the page again - refresh the page - it transition from dark theme to white theme, is this a know issue?

prefer-color-scheme overrides permanent ?

Hi,

Firstly, great post at web.dev + good job with the element.

Just running into a wee issue. We have the following HTML,

<dark-mode-toggle appearance="toggle" permanent dark="Dark Theme" light="Light Theme"></dark-mode-toggle>

When the user toggles the color scheme, either via OS or via Chrome dev tools, the permanent setting is lost. Not sure if I got something wrong or I missed some detail or is this behaviour expected?

Example scenario: User OS theme set to dark. User visits website, dark theme loads by default. User changes website setting to light. User then changes OS them from dark to light and back to dark. The website switches to dark theme.

Also, is it possible to remove the outline in CSS (example would be handy), or even better add a ripple effect? Our website uses mdc-web-components. An example with a material text button as toggle would be super handy.

Cheers.

Icon Flash on Mouse Hover

When using custom PNGs for the light/dark, I'm seeing a brief flash of the icon when the mouse hovers over the icon and when moving off of the icon. Using the OOTB icons this doesn't happen.

dark-mode-toggle {
  position: absolute;
  top: 0.5rem;
  right: 1rem;
  --dark-mode-toggle-light-icon: url(/assets/moon.png);
  --dark-mode-toggle-dark-icon: url(/assets/sun.png);
  --dark-mode-toggle-icon-size: 2rem;
  --dark-mode-toggle-icon-filter: invert(100%);
  transform:translate3d(0, 0, 0);
}

Not sure why this would be happening with custom PNGs.

Transition question

First off, this is dope. Thank you.

I have a question about smooth transitions. I'm not a very experienced front-end developer, I'm a photographer trying to build my own stuff to avoid hosting fees while times are tough, and using the spare time to learn some html/css/js.

I stumbled across this on web.dev when trying how to get a theme for a static site generator to default the OS light/dark but remember overwritten user controls.

In that article, you have..
`body {
--duration: 0.5s;
--timing: ease;

color: var(--color);
background-color: var(--background-color);

transition:
color var(--duration) var(--timing),
background-color var(--duration) var(--timing);
}`
But there is no mention of it in the github version. With it still applied, the page blips from light to dark when the mode is permanent. I was curious what I need to look at specifically to fix that.

Reloading in the demo in dark mode still causes an initial flash of the light theme.

Can this be improved so that's there's no flash? I was considering your script because is similar to the way I implemented it on my site that is with a class that overrides custom styles but I have this very same problem which is kind of annoying for users in particular for dark mode as it blinds you for a sec. I forgot to mention: tested this on the demo site with remember preference on.

Failed to load module script: The server responded

hi i wanted to download the source code and run it on localhost but unfortunately i get this error every time. what's the problem ? how can i solve?

no changes have been made to the file I get this error even when I want to use the demos

Failed to load module script: The server responded with a non-JavaScript MIME type of "". Strict MIME type checking is enforced for module scripts per HTML spec.

customElements is not defined

Hello @tomayac,

In old browsers like Firefox 52, there is no support for Custom Elements. I'm using Webpack with Babel and I can't find a plugin to support Custom Elements. So i suggest you to do nothing if customElements is not defined.

// Do nothing if `customElements` does not exist. 
if (!window.customElements) return;

Thank you in advance !

Flashes when system prefers dark, but light theme is toggled

This even happens on the demo site. https://googlechromelabs.github.io/dark-mode-toggle/demo/index.html

Tested on both Chrome and Firefox.

System must be configured to prefer dark, then light theme must be toggled on and remembered in the site. On page change or refresh, sometimes you'll get a frame or two where the dark theme is rendered first, then it flips over to the light theme as expected. With the demo site, because there's a transition enabled, you get the dark theme fading back into the light theme.

Hopefully a workaround is found for this!

Problems styling ::parts and pseudo elements such as ::before

Hi, well its been interesting to learn about Shadow CSS and ::parts but how can I style :: before and ::after using parts? It seems is not possible to target both at the same time. In my case I need to set different values for icons in the select button/form for width and height so it seems current variables are not enough. Maybe the code related to the toggle/switch could be further simplified.

Class based

I built practically the same system for a site i'm working on but I actually really like some of the ideas you have put in here. My issue is that my dark/light styling is controlled via a high-level class. Could this be tweaked to allow a top-level class to be used rather than multiple stylesheets?

Thanks

Consider aria-label="auto" aria-live="polite"

I am a junior Dev and While implementing dark-mode-toggle and my other study from the below Google article I came across
aria-label="auto" aria-live="polite" for theme component.

https://web.dev/building-a-theme-switch-component/

In this, we keep the aria-label auto by default and change it to "light" or "dark" based on our toggle switch.
Also aria-live="polite" seems to add up.

If possible kindly have a look at these enhancements if deemed appropriate.

Minified version is broken

Currently terser is configured to minify all properties, and ends up even minifying access to attribute reflections.

For example:

this.permanent = event.detail.permanent;
this.permanentCheckbox.checked = this.permanent;

is currently minified to

        (this.g = e.detail.g), (this.p.checked = this.g);

so it ends up accessing invalid properties, and same in other places.

Remember

Hey,

I find that the remember feature doesn't seem to work for me. I load the site with my OS appearance set to light, the site shows in light, I then toggle to dark which the dark-mode-toggle and click remember. I see the local storage key getting set. I refresh the page and it shows in light, the local storage key also switched the light. Any ideas?

Also, once the above is working, what does it do if you switch the OS mode to be equal to the permanent setting, does this remove the local storage key as they will match and are no longer required? This would be a cool feature to have.

Extra margin

I have my toggle set up as a toggle and the permanent attribute set. The icon I am using has a 1x1 aspect but I get some random margin on the right and bottom so the width doesn't match the height?

How can I remove these margins?

Also a way to be able to remove or alter the style of the focus styles would be useful.

Apart from `light` and `dark`, add a `system` option

Is there any way (currently) or are there any plans on adding a system theme option that would just reflect the system and not override it? Or do I have to somehow make a custom one that clears the localStorage?

Vertical spacing on checkbox label is off

Thanks for making this handy tool. It's really easy to just plug in and get working.

The icon needs a bit of bottom margin so that it is horizontally aligned with the label text:

spacing

The margin on label::before should be something like 0 .5rem .16rem 0, not 0 .5rem 0 0.

Alternatively, I think there's a way to put both elements in a flex container and align-content: center.

I can't override it myself since it is in a shadow dom.

[feature request] support SRI (sub resources integrity)

Currently if CSP (content security policy) does not already include unsafe-inline, client browser will refuse to load inline styles from this web component.

Due to the way this project is built it is not very easy for developers to get around this limitation.

Can't get to work

Hey,

I've pretty much copied the examples and put the dark-mode-toggle markup into my code but I see absolutely no output. The element has no width or height or anything. Any ideas where I may be going wrong?

Unable to Load png files when running on Github Pages

It is somewhat weird that the png files are loading when I ran locally but were unable to load properly after committing the code to Github and ran using Github pages. (I am able to use the button but it is transparentπŸ€·β€β™‚οΈ.)
I am unable to figure out what is happening?

Link to Source Code

Local The moon png in the navigation bar
image

Github Pages
image

Code Snippets:
CSS
image

HTML
image

HEAD
image

dark mode switch error

When dark mode is active, when I refresh the page, it loads "LIGHT" first and then goes into dark mode. how can i fix this. If dark is selected, install dark.
it seems a little silly to start "light" first and switch to darkness immediately. I wonder if there is an error in my codes. I'm waiting for your help
you understand what I want to say from the video.
video

<meta name="color-scheme" content="dark light"/>
<meta name="theme-color" content="rgb(174, 129, 7)"/>
<link rel="icon" content="">
<link rel="stylesheet" href="'dark-mode/styles/light.css'" media="(prefers-color-scheme: light)">
<link rel="stylesheet" href="'dark-mode/styles/dark.css'" media="(prefers-color-scheme: dark)">
<link rel="stylesheet" href="'dark-mode/styles/common.css'">
<script type="module" src="'dark-mode/scripts/dark-mode-toggle.mjs'"></script>
<script type="module" src="'dark-mode/scripts/dark-mode-toggle-playground.mjs'"></script>
script
    if (window.matchMedia('(prefers-color-scheme)').media === 'not all') {
        document.documentElement.style.display = 'none';
        document.head.insertAdjacentHTML(
            'beforeend',
            '<link rel="stylesheet" href="dark-mode/styles/light.css" onload="document.documentElement.style.display = ``">'
        );
    }
</script>
<aside><dark-mode-toggle id="dark-mode-toggle-2" permanent></dark-mode-toggle></aside>

Flash of wrong styles

Great project overall, its a nice inspiration!

All solutions I discovered on the web with a permenent switch and also my own custom code suffer from a flash of the wrong styles at some point before the styles accoring to localStorage setting is applied. This happens in latest Chrome, but not in Desktop and Mobile Safari.

your regular demo does (on page reload) and v8.dev also, only your barebones demo seems fast enough

is it just not possible to avoid a flash (e.g. white background flash before dark background gets applied) without blocking the rendering or hiding the page or do have a suggestion?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.