UNPKG

preline

Version:

Preline UI is an open-source set of prebuilt UI components based on the utility-first Tailwind CSS framework.

295 lines (207 loc) 10.2 kB
# Theme Switch Style your site in dark mode with ready made Preline UI's dark mode toggle plugin. [![npm](https://img.shields.io/badge/npm-v4.2.0-blue)](https://www.npmjs.com/package/@preline/theme-switch) [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) [![Demo](https://img.shields.io/badge/demo-online-brightgreen)](https://preline.co/plugins/theme-switch.html) ## Contents - [Overview](#overview) - [Installation](#installation) - [Toggling dark mode manually](#toggling-dark-mode-manually) - [Basic usage](#basic-usage) - [Configuration Options](#configuration-options) - [JavaScript API](#javascript-api) - [Events](#events) - [Common Patterns](#common-patterns) - [License](#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. ```bash npm i @preline/theme-switch ``` ### CSS Use [`@source`](https://tailwindcss.com/docs/functions-and-directives#source-directive) to register the plugin's JavaScript path for Tailwind CSS scanning, then [`@import`](https://tailwindcss.com/docs/functions-and-directives#import-directive) the plugin's CSS files into your Tailwind CSS file. ```css @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: ```html <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. ```html <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. ```js 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. ```js 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. ```html <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:** ```html <!-- 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'`)<br>`isSaveToLocalStorage`: `boolean` (optional)<br>`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)<br>`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** ```javascript // 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** ```javascript // 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** ```javascript 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 ```javascript // 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. ```html <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. ```html <input type="checkbox" data-hs-theme-switch> <label>Dark Mode</label> ``` ### Pattern 3: Programmatic Control Control theme programmatically. ```html <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](https://opensource.org/licenses/MIT).