VToggleTheme: Theme Switcher Component
This Vue component provides intelligent theme switching for Vuetify-based applications. It can automatically switch between light and dark themes based on sunrise and sunset times, respect the user's system theme preference (prefers-color-scheme
), or allow manual toggling. Seamlessly integrates with Vuetify and works with SSR and Nuxt 3.
Features
- Automatic Theme Switching: Updates the theme based on real-time sunrise/sunset times.
- Manual Override: Allows users to manually switch themes, disabling automatic switching.
- System Theme Preference Support: Optionally respects the user's operating system theme (light/dark) via
prefers-color-scheme
, bypassing automatic switching when appropriate. - Vuetify Integration: Seamlessly integrates with Vuetify's theming system.
- Location-Based Switching: Uses a fixed fallback location to determine sunrise and sunset times, without requiring browser geolocation.
Note: The component does not access the user's actual geolocation by default. Instead, it uses a developer-provided fallback location (e.g., company HQ or server location) to calculate sunrise and sunset times. This ensures consistent behavior across users without requiring browser permission prompts.
- SSR Compatibility: Ensures correct operation in both client and server-side environments.
- Nuxt3 Compatibility: Fully compatible with Nuxt3 for seamless integration.
Requirements
- Vue 3.x: Required as the component is built using the Composition API and Vue 3 features.
- Vuetify 3.x: Required for theme integration and UI components.
- @mdi/js (optional): Only needed if you want to use inline SVG icons. Otherwise, Vuetify’s MDI font icons are used by default.
This component internally uses sunrise-sunset-js
to calculate sunrise and sunset times. It is installed automatically and does not need to be added manually.
Installation
Install the component via npm:@mdi/js
is only required if you prefer not to use @mdi/font
.
npm install v-toggle-theme @mdi/js
Additionally, install the required peer dependencies:
npm install vue@^3.5.13 vuetify@^3.7.5
Usage
Props
themeNameLight
(String
): Name of the light theme. Default:'light'
.- Example:
:themeNameLight="'myLightTheme'"
- Example:
themeNameDark
(String
): Name of the dark theme. Default:'dark'
.- Example:
:themeNameDark="'myDarkTheme'"
- Example:
fallbackLocation
(Object
): Default coordinates for sunrise and sunset. Default:{ lat: 47.36667, lng: 8.55 }
(Zurich).- Example:
:fallbackLocation="{ lat: 40.7128, lng: -74.0060 }"
(New York)
- Example:
tooltip
(Boolean
): Enables tooltips. Default:false
.- Example:
:tooltip="true"
- Example:
tipDark
(String
): Tooltip text for dark mode. Default:'Dark mode'
.- Example:
:tipDark="'Activate dark mode'"
- Example:
tipLight
(String
): Tooltip text for light mode. Default:'Light mode'
.- Example:
:tipLight="'Activate light mode'"
- Example:
automatic
(Boolean
): Enables automatic theme switching based on sunrise/sunset. Default:true
.- Example:
:automatic="false"
- Example:
usePreference
(Boolean
): Enables detection of the user's system theme setting viaprefers-color-scheme
. Iftrue
, the component uses the OS theme (light/dark) as-is. If the system reports dark mode, it enforces dark mode regardless of time orautomatic
. If the system reports light mode during night hours, it assumes the user prefers light mode and disables automatic switching. Default:false
.- Example:
:usePreference="true"
- Example:
mdiJsIcons
(Boolean
): Use @mdi/js icons. Default:false
.- Example:
:mdi-js-icons="true"
- Example:
Integration
Options API
<script>
import VToggleTheme from 'v-toggle-theme';
export default {
components: {
VToggleTheme
}
}
</script>
<template>
<v-toggle-theme color="primary" :tooltip="true" />
</template>
Composition API
<script setup>
import VToggleTheme from 'v-toggle-theme';
</script>
<template>
<v-toggle-theme color="primary" :tooltip="true" />
</template>
System Preference Example
<template>
<!-- Uses the system's dark/light preference instead of sunrise/sunset -->
<v-toggle-theme :usePreference="true" :tooltip="true" />
</template>
Events
switchManually
: Toggles the theme manually and stops automatic switching.
Customization
Customize the switch appearance using Vuetify's v-btn properties. Modify themeNameLight
and themeNameDark
according to your Vuetify theme settings for deeper integration.
License
Licensed under the GNU Lesser General Public License as published by the Free Software Foundation, either version 2.1 of the License, or (at your option) any later version.
Acknowledgements
Thanks to Matt Kane (@ascorbic) for creating the sunrise-sunset-js
package, a crucial tool for this project.
Changelog
v3.2.0
- Added new
usePreference
prop to respect system theme (viaprefers-color-scheme
) - If
usePreference
is enabled and the system reports light mode during night hours, the component assumes this is a deliberate user preference - Manual toggling still overrides all logic, including system and automatic settings