@preline/theme-switch
v4.2.0
Published
Preline UI is an open-source set of prebuilt UI components based on the utility-first Tailwind CSS framework.
Readme
Theme Switch
Style your site in dark mode with ready made Preline UI's dark mode toggle plugin.
Contents
- Overview
- Installation
- Toggling dark mode manually
- Basic usage
- Configuration Options
- JavaScript API
- Events
- Common Patterns
- License
Overview
The Theme Switch component provides functionality to toggle between light and dark themes. It manages theme state, saves preferences to localStorage, and integrates with Tailwind CSS dark mode functionality.
Key Features:
- Light/dark theme switching
- System theme detection
- LocalStorage persistence
- Tailwind CSS integration
- Programmatic control via JavaScript API
- Event system for theme changes
Installation
To get started, install Theme Switch plugin via npm, else you can skip this step if you are already using Preline UI as a package.
npm i @preline/theme-switchCSS
Use @source to register the plugin's JavaScript path for Tailwind CSS scanning, then @import the plugin's CSS files into your Tailwind CSS file.
@import "tailwindcss";
/* @preline/theme-switch */
@source "../node_modules/@preline/theme-switch/*.js";
@import "./node_modules/@preline/theme-switch/variants.css";
@import "./node_modules/@preline/theme-switch/theme.css";JavaScript
Include the JavaScript that powers the interactive elements near the end of your </body> tag:
<script src="./node_modules/@preline/theme-switch/index.js"></script>Manual Initialization
Use the non-auto entry if you need manual initialization. In this mode, automatic initialization on page load is not included, so the component should be initialized explicitly.
<script type="module">
import HSThemeSwitch from "@preline/theme-switch/non-auto.mjs";
new HSThemeSwitch(document.querySelector("#theme-switch"));
</script>Via Bundler
When using a bundler (Vite, webpack, etc.), import the plugin directly as an ES module.
@preline/theme-switch is the auto-init entry: it scans the DOM and initializes matching elements automatically.
import "@preline/theme-switch";@preline/theme-switch/non-auto is the manual entry: use it when you want explicit control over when initialization happens, either via autoInit() or by creating a specific instance yourself.
import HSThemeSwitch from "@preline/theme-switch/non-auto";
HSThemeSwitch.autoInit();
// Or initialize a specific element manually
const el = document.querySelector("#theme-switch");
if (el) new HSThemeSwitch(el);TypeScript
This package ships with TypeScript type definitions. No additional @types/ package is needed.
Basic usage
The following example demonstrates the minimal HTML structure required for a theme switch component. This is a base template without custom styling - you can apply your own CSS classes and styles as needed. Clicking the button toggles between light and dark themes.
<button type="button" class="hs-dark-mode hs-dark-mode-active:hidden block" data-hs-theme-click-value="dark">
Dark
</button>
<button type="button" class="hs-dark-mode hs-dark-mode-active:inline-flex hidden" data-hs-theme-click-value="light">
Light
</button>Structure Requirements:
data-hs-theme-click-value: Required on button elements, specifies the theme value ('default','dark', or'auto')hs-dark-mode: Required class for theme-aware styling- Buttons can be separate elements or combined into one toggle
Initial State:
- Theme is determined by system preference or saved preference
- Appropriate button is shown/hidden based on current theme
Configuration Options
Data Options
Data options are specified via data attributes.
| Attribute | Target Element | Type | Default | Description |
| --- | --- | --- | --- | --- |
| data-hs-theme-click-value | Button element | 'default' | 'dark' | 'auto' | 'default' | When you click on an element with this attribute, the theme changes to the one specified in the attribute. Should be added to the button (trigger). |
| data-hs-theme-switch | Input element (checkbox/radio) | - | - | When you change an element with this attribute, the theme changes to the opposite one. Element should have change event, e.g. checkbox or radio button. Should be added to the input (checkbox). |
Example:
<!-- Click-based toggle -->
<button data-hs-theme-click-value="dark">Dark Mode</button>
<!-- Change-based toggle -->
<input type="checkbox" data-hs-theme-switch>Tailwind Modifiers
| Name | Description |
| --- | --- |
| hs-dark-mode-active:* | Defines CSS classes when dark mode is ON |
| hs-default-mode-active:* | Defines CSS classes when default (light) mode is ON |
| hs-default-auto-active:* | Defines CSS classes according to the System theme |
JavaScript API
The HSThemeSwitch object is available in the global window object after the plugin is loaded.
Instance Methods
These methods are called on a theme switch instance.
| Method | Parameters | Return Type | Description |
| --- | --- | --- | --- |
| setAppearance(theme, isSaveToLocalStorage, isSetDispatchEvent) | theme: string (optional, 'dark' | 'light' | 'default')isSaveToLocalStorage: boolean (optional)isSetDispatchEvent: boolean (optional) | void | Sets the appearance/theme programmatically. theme specifies the theme to set. isSaveToLocalStorage determines whether to save to localStorage (default: true). isSetDispatchEvent determines whether to dispatch the theme change event (default: true). |
| destroy() | None | void | Destroys the theme switch instance, removes all generated markup, classes, and event listeners. Use when removing theme switch from DOM. |
Static Methods
These methods are called directly on the HSThemeSwitch class.
| Method | Parameters | Return Type | Description |
| --- | --- | --- | --- |
| HSThemeSwitch.getInstance(target, isInstance) | target: HTMLElement \| string (CSS selector)isInstance: boolean (optional) | HTMLElement \| { id: string \| number, element: HSThemeSwitch } \| null | Returns the theme switch instance or element associated with the target. If isInstance is true, returns collection item object { id, element } where element is the HSThemeSwitch instance. If isInstance is false or omitted, returns the DOM element (HTMLElement). Returns null if theme switch instance is not found. |
Usage Examples
Example 1: Setting theme programmatically
// Get the theme switch instance
const instance = HSThemeSwitch.getInstance('[data-hs-theme-click-value]', true);
if (instance) {
const { element } = instance;
// Set dark theme
element.setAppearance('dark');
// Set light theme
element.setAppearance('light');
// Set theme without saving to localStorage
element.setAppearance('dark', false);
}Example 2: Getting instance and accessing properties
// Get the theme switch instance
const instance = HSThemeSwitch.getInstance('[data-hs-theme-click-value]', true);
if (instance) {
const { element } = instance;
// Access instance properties
console.log('Current theme:', element.theme);
console.log('Type:', element.type);
// Clean up when removing from DOM
function removeThemeSwitch() {
element.destroy();
}
}Example 3: Destroying theme switch instance
const instance = HSThemeSwitch.getInstance('[data-hs-theme-click-value]', true);
if (instance) {
const { element } = instance;
const removeBtn = document.querySelector('#hs-remove-btn');
removeBtn.addEventListener('click', () => {
// Clean up before removing from DOM
element.destroy();
// Now safe to remove the element
document.querySelector('[data-hs-theme-click-value]').remove();
});
}Events
Theme switch instances emit global events that can be listened to for theme change tracking.
| Event Name | When Fired | Callback Parameter | Description |
| --- | --- | --- | --- |
| on-hs-appearance-change | Every time the mode changes | None | An event that fires every time the mode changes. This is a global window event, not an instance event. |
Event Usage Example
// Listen to global theme change event
window.addEventListener('on-hs-appearance-change', () => {
console.log('Theme changed!');
// Perform actions after theme changes
// e.g., update UI, reload resources, track analytics
});Common Patterns
Pattern 1: Click-based Toggle
Use buttons to toggle between themes.
<button data-hs-theme-click-value="dark">Dark</button>
<button data-hs-theme-click-value="light">Light</button>Pattern 2: Checkbox Toggle
Use a checkbox to toggle theme.
<input type="checkbox" data-hs-theme-switch>
<label>Dark Mode</label>Pattern 3: Programmatic Control
Control theme programmatically.
<button id="hs-dark-btn">Dark</button>
<button id="hs-light-btn">Light</button>
<script>
const instance = HSThemeSwitch.getInstance('[data-hs-theme-click-value]', true);
if (instance) {
const { element } = instance;
document.querySelector('#hs-dark-btn').addEventListener('click', () => {
element.setAppearance('dark');
});
document.querySelector('#hs-light-btn').addEventListener('click', () => {
element.setAppearance('light');
});
}
</script>License
Copyright (c) 2026 Preline Labs.
Licensed under the MIT License.
