Skip to content

VvColorModeButton Component

The VvColorModeButton Component provides a localStorage() based solution to quickly implement and manage a user's dark or light color mode setting (with optional unnoticeable faux-persistence) for a VueVentus powered application.

Import

To import a VvColorModeButton Component installed by the vueventus CLI or vv-update CLI:

javascript
// ./src/components/SomeComponent.vue
import VvColorModeButton from './vv/buttons/VvColorModeButton.vue'

TIP

CLI installed components pass through VueVentus defaults via component props. Each prop default value can be customized globally by overriding VvConfig defaults in your app ./src/app.vv.ts file or singularly in a component instance.

Alternatively, you can install the raw library VvColorModeButton Component with:

javascript
import { VvColorModeButton } from '@obewds/vueventus'

TIP

Importing raw VueVentus library components will still apply your ./src/app.vv.ts settings automatically through the Vue provide() and inject() pattern. All raw VueVentus library components automatically check for a provided "vv" keyed object with a ConfigVv type interface.

CLI or Raw?

The main difference between raw library components and CLI installed components, is that you have no control over component defaults with raw library components. This is less flexible than using CLI installed components, because control of component defaults can greatly reduce the number of props a dev has to type for component instances, which reduces app code.

Meanwhile, the control CLI installed components provide through customizable defaults, opens up to a global level (styling management system) control for default component state characteristic values (particularly powerful with color and proportional size characteristics).

Manual Installation

Manually installing the VvColorModeButton Component requires a little bit of extra work due to the nature of Color Modes and JavaScript applications in browser contexts.

To get this component working without any FOUC, you'll want to access your app's main/base HTML structure's <head> tag, and add a script. This script needs to run before the body is parsed and before the Vue app runs, to synchronize the user's session and any already existing localStorage color mode data a user may have already from this setup.

Here's the script that needs to be added to an app's main/base HTML:

html
<html lang="en">

    <head>
        
        <!-- ... -->

        <!-- Color Mode Functionality -->
        <script>
            // On page load or when changing colorMode, best to add inline in `head` to avoid FOUC
            if (document && localStorage) {
                if (localStorage.colorMode === 'dark' || (!('colorMode' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
                    localStorage.setItem('colorMode', 'dark');
                    document.documentElement.classList.add('dark');
                    document.documentElement.style.backgroundColor = '#242426';
                    document.documentElement.style.color = '#e1e1e3';
                } else {
                    localStorage.setItem('colorMode', 'light');
                    document.documentElement.classList.remove('dark');
                    document.documentElement.style.backgroundColor = '#e1e1e3';
                    document.documentElement.style.color = '#242426';
                }
            }
        </script>

    </head>

    <body>...</body>

</html>

Additionally and for completeness when installing of the VvColorModeButton Component, after adding the script above to a code base there's still one more important step to do.

It's generally a good idea to go ahead and add an additional localStorage check within Vue, so Vue and the application both match what the script above adds to localStorage on page load, like this:

html
<script setup lang="ts">

    // ./src/App.vue

    import VvColorModeButton from './components/vv/buttons/VvColorModeButton.vue'

    const colorMode = localStorage && localStorage.getItem('colorMode') ? localStorage.getItem('colorMode') : 'light'

</script>

<template>

    <main>

        <aside class="fixed bottom-0 right-0 text-right z-40">

            <nav class="relative bottom-0 pb-3 pr-4">

                <div class="flex flex-col justify-end space-y-3">

                    <VvColorModeButton :mode="(colorMode as string)"/>

                </div>

            </nav>

        </aside>

    </main>

</template>

Prop: color

Type: String
Default: "default"

The VvColorModeButton Component color prop sets the component instance color based both on the color prop and the palette prop value together.

Syntax

html
<VvColorModeButton color="primary"/>

Result

WARNING

You may have to click this component a couple of times as VitePress's awesome template (used to make these docs) has it's own dark/light mode functionality and they both kinda work together because they both add/remove a .dark class from the app!

That said, if you click these example elements a few times, then they will take over the page from VitePress!

Typing for Downstream Component Instances

Coming Soon!

Prop: debug

Type: Boolean
Default: false

The VvColorModeButton Component debug prop toggles the debugging state of a component instance. When in debugging mode, each component instance prop value can be viewed through data-vv-color-mode-button- prefixed HTML attributes.

Syntax

html
<VvColorModeButton :debug="true"/>

Result

Prop: groundDark

Type: String
Default: "dark:bg-gray-900"

The VvColorModeButton Component groundDark prop sets the component instance class(es) for the background color of the application when in the dark color mode state.

Syntax

html
<VvColorModeButton ground-dark="bg-gray-900"/>

Result

WARNING

You may have to click this component a couple of times as VitePress's awesome template (used to make these docs) has it's own dark/light mode functionality and they both kinda work together because they both add/remove a .dark class from the app!

That said, if you click these example elements a few times, then they will take over the page from VitePress!

Prop: groundDarkHex

Type: String
Default: "#242426"

The VvColorModeButton Component groundDarkHex prop sets the component instance color code for the background color of the application when in the dark color mode state.

Syntax

html
<VvColorModeButton ground-dark-hex="#242426"/>

Result

WARNING

You may have to click this component a couple of times as VitePress's awesome template (used to make these docs) has it's own dark/light mode functionality and they both kinda work together because they both add/remove a .dark class from the app!

That said, if you click these example elements a few times, then they will take over the page from VitePress!

Prop: groundLight

Type: String
Default: "bg-gray-100"

The VvColorModeButton Component groundLight prop sets the component instance class(es) for the background color of the application when in the light color mode state.

Syntax

html
<VvColorModeButton ground-light="bg-gray-100"/>

Result

WARNING

You may have to click this component a couple of times as VitePress's awesome template (used to make these docs) has it's own dark/light mode functionality and they both kinda work together because they both add/remove a .dark class from the app!

That said, if you click these example elements a few times, then they will take over the page from VitePress!

Prop: groundLightHex

Type: String
Default: "#e1e1e3"

The VvColorModeButton Component groundLightHex prop sets the component instance color code for the background color of the application when in the light color mode state.

Syntax

html
<VvColorModeButton ground-light-hex="#e1e1e3"/>

Result

WARNING

You may have to click this component a couple of times as VitePress's awesome template (used to make these docs) has it's own dark/light mode functionality and they both kinda work together because they both add/remove a .dark class from the app!

That said, if you click these example elements a few times, then they will take over the page from VitePress!

Prop: mode

Type: String
Valid Values: ValidColorModes Module
Default: "light"

The VvColorModeButton Component type prop sets the button HTML type attribute to a value that should be present in the ValidColorModes Module to be a valid value for this component.

Syntax

html
<VvColorModeButton mode="light"/>

Result

WARNING

You may have to click this component a couple of times as VitePress's awesome template (used to make these docs) has it's own dark/light mode functionality and they both kinda work together because they both add/remove a .dark class from the app!

That said, if you click these example elements a few times, then they will take over the page from VitePress!

Typing for Downstream Component Instances

Coming Soon!

Prop: palette

Type: String
Default: "outline"

The VvColorModeButton Component palette prop sets the component instance color based both on the palette prop and the color prop values together.

Syntax

html
<VvColorModeButton palette="solid"/>

Result

WARNING

You may have to click this component a couple of times as VitePress's awesome template (used to make these docs) has it's own dark/light mode functionality and they both kinda work together because they both add/remove a .dark class from the app!

That said, if you click these example elements a few times, then they will take over the page from VitePress!

Typing for Downstream Component Instances

Coming Soon!

Prop: size

Type: String
Default: "xs"

The VvColorModeButton Component size prop sets the component instance size-based classes which in the context of buttons typically involves padding and font size atomic classes.

Syntax

html
<VvColorModeButton size="xl"/>

Result

WARNING

You may have to click this component a couple of times as VitePress's awesome template (used to make these docs) has it's own dark/light mode functionality and they both kinda work together because they both add/remove a .dark class from the app!

That said, if you click these example elements a few times, then they will take over the page from VitePress!

Typing for Downstream Component Instances

Coming Soon!

Prop: textDark

Type: String
Default: "dark:text-gray-100"

The VvColorModeButton Component textDark prop sets the component instance class(es) for the text color of the application when in the dark color mode state.

Syntax

html
<VvColorModeButton text-dark="text-gray-100"/>

Result

WARNING

You may have to click this component a couple of times as VitePress's awesome template (used to make these docs) has it's own dark/light mode functionality and they both kinda work together because they both add/remove a .dark class from the app!

That said, if you click these example elements a few times, then they will take over the page from VitePress!

Prop: textLight

Type: String
Default: "text-gray-900"

The VvColorModeButton Component textLight prop sets the component instance class(es) for the text color of the application when in the light color mode state.

Syntax

html
<VvColorModeButton text-light="text-gray-900"/>

Result

WARNING

You may have to click this component a couple of times as VitePress's awesome template (used to make these docs) has it's own dark/light mode functionality and they both kinda work together because they both add/remove a .dark class from the app!

That said, if you click these example elements a few times, then they will take over the page from VitePress!

Prop: titleDark

Type: String
Default: "Enable Dark Mode"

The VvColorModeButton Component titleDark prop sets the component instance title attribute string of the component when the app is currently in the dark color mode state.

TIP

The state contexts in this component uses the opposite title text of the visible icon and color mode state, giving screen readers an accurate description of what clicking the component will do! So the dark mode title points to enable the light mode and the light mode title point to enable the dark mode!

Syntax

html
<VvColorModeButton title-dark="Custom Enable Light Mode"/>

Result

WARNING

You may have to click this component a couple of times as VitePress's awesome template (used to make these docs) has it's own dark/light mode functionality and they both kinda work together because they both add/remove a .dark class from the app!

That said, if you click these example elements a few times, then they will take over the page from VitePress!

Prop: titleLight

Type: String
Default: "Enable Light Mode"

The VvColorModeButton Component titleLight prop sets the component instance title attribute string of the component when the app is currently in the light color mode state.

TIP

The state contexts in this component uses the opposite title text of the visible icon and color mode state, giving screen readers an accurate description of what clicking the component will do! So the dark mode title points to enable the light mode and the light mode title point to enable the dark mode!

Syntax

html
<VvColorModeButton title-light="Custom Enable Dark Mode"/>

Result

WARNING

You may have to click this component a couple of times as VitePress's awesome template (used to make these docs) has it's own dark/light mode functionality and they both kinda work together because they both add/remove a .dark class from the app!

That said, if you click these example elements a few times, then they will take over the page from VitePress!

Prop: type

Type: String
Valid Values: ValidButtonTypes Module
Default: "button"

The VvColorModeButton Component type prop sets the button HTML type attribute to a value that should be present in the ValidButtonTypes Module to be a valid value for this component.

Syntax

html
<VvColorModeButton type="submit"/>

Result

Typing for Downstream Component Instances

Coming Soon!

Slot: None

NO SLOT AVAILABLE

The VvColorModeButton Component does not have Vue slot option, because the component uses two heroicons and is intended to output an equal in height and width <button> element that toggles between two icons and leverages HTML title attributes to compensate for the use of non-text iconography.

Released under the MIT License