npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

favicon-mode-switcher

v1.1.1

Published

🕯 Make your favicon adapt to dark and light mode

Downloads

928

Readme

 
 

   
   

Installation

You can install favicon-mode-switcher using the package manager of your choice or load it through a CDN:

npm:

npm install favicon-mode-switcher

yarn:

yarn add favicon-mode-switcher

CDN (unpkg):

<script type="module">
  import faviconModeSwitcher from 'https://unpkg.com/favicon-mode-switcher/dist/index.min.mjs'
  // ...
</script>

or the UMD build:

<script src="https://unpkg.com/favicon-mode-switcher">

💡 Since all browsers supporting (prefers-color-scheme) also support JavaScript modules, usage of the module version is highly recommended. The UMD build is only meant for scenarios where you can't use <script type="module">, for example when inserting the script using a WordPress hook.

 

Usage

TL;DR

import faviconModeSwitcher from 'favicon-mode-switcher'
// or
const faviconModeSwitcher = require('favicon-mode-switcher')
// or
const faviconModeSwitcher = window.faviconModeSwitcher.default

// then...

faviconModeSwitcher('link[rel="shortcut icon"]')
// or
faviconModeSwitcher(document.querySelector('#favicon'))
// or
faviconModeSwitcher({
  element: document.querySelector('#favicon'),
  href: { dark: '/icons/favicon-light.ico' },
})

 

The module exports a single function as default export. If the UMD build is used, this function will be exposed on window.faviconModeSwitcher.default. It has the following type signature:

function faviconModeSwitcher(FaviconTarget | FaviconTarget[] | NodeListOf<HTMLLinkElement>): DestroyFunction

It takes either the configuration for a single icon to be updated, or an Array containing multiple configurations if you want to keep many icons in sync with the active color scheme. NodeList is supported too, so you can use it with document.querySelectorAll().

🕯 Even though it's technically not an icon, you can also update the web app manifest (<link rel="manifest">) of your website using favicon-mode-switcher!

The configuration for an icon is either:

  • a CSS selector string, which has to return a <link> element when passed to document.querySelector()
  • a <link> element itself
  • an Object, containing one of the above as the element property, along with an optional href config
type FaviconTarget =
  | string
  | HTMLLinkElement
  | {
      element: string | HTMLLinkElement
      href?: { dark?: string; light?: string }
    }

 

Automatic href updates

If you use a selector, Element or Object without href property as icon config, the icon's href will be updated automatically. For this, favicon-mode-switcher will look for the substring "dark" or "light" in the href you specified in the HTML and replace it with the currently active color scheme. For example: here, the href will be replaced with ./my-favicon.dark.ico whenever the device is in dark mode:

<link rel="shortcut icon" href="./my-favicon.light.ico" />

(if the href in the HTML doesn't contain either "light" or "dark", nothing will happen)

 

Specyfing the href to use

Alternatively, you can specify href configuration when using an Object. The object keys must match a color scheme and the value is the href that should be used when the color scheme from the key is active. For example: with the following config the href of <link id="icon"> will be set to ./logo-teal.ico while the device is in dark mode, and logo-navyblue.ico while the device is in light mode.

{ element: '#icon', href: { dark: './logo-teal.ico', light: './logo-navyblue.ico' } }

However, you only need to specify the href for one color scheme:
If there is no href defined for the color scheme that is currently active, favicon-mode-switcher will simply use the one that was initially specified in the HTML.

 

Stopping the mode switcher

The main function described above returns a destroy function when called. Run it and the switcher will stop and reset all the icons to their original href:

const destroyIconSwitcher = faviconModeSwitcher(document.querySelectorAll('.favicon'))

// later...
destroyIconSwitcher()

 

Browser Support & SSR

Detecting the active color scheme is a relatively new feature and as such has limited browser support. The script itself should run in any browser from at least Internet Explorer 9 upwards without throwing an error, so you can use it for Progressive Enhancement.
It also doesn't throw if window is undefined, so you can safely require and execute it in a Node environment for SSR.

Note that the ESModule versions (.mjs file extension) only work in browsers with support for ES2015 / ES6. Modern bundlers like webpack will automatically import these versions by default. If you're using such a bundler and need legacy browser support, either transpile the module yourself or directly import the CommonJS version at dist/index.js.

   
 


PRs welcome!

 

© 2021, Jonas Kuske