# blockenberg/2.0.7/blocks/dark-mode-toggle/frontend.js

Blockenberg — 600+ Advanced Gutenberg Blocks &amp; AI Agent for WordPress Block Editor, version 2.0.7. 186 lines.

- Page: https://pluginprobe.com/plugins/blockenberg/2.0.7/code/blocks/dark-mode-toggle/frontend.js
- Raw: https://pluginprobe.com/plugins/blockenberg/2.0.7/raw/blocks/dark-mode-toggle/frontend.js
- Modified: 2026-03-06T12:32:40+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/blockenberg/2.0.7/code/blocks/dark-mode-toggle/frontend.js#L10-L20`.

```javascript
(function () {
    'use strict';

    function reducedMotion() {
        return window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
    }

    function initToggle(wrap) {
        var cfg = {
            toggleStyle:   wrap.dataset.toggleStyle   || 'switch',
            position:      wrap.dataset.position       || 'inline',
            floatCorner:   wrap.dataset.floatCorner    || 'bottom-right',
            floatX:        parseInt(wrap.dataset.floatX, 10)  || 24,
            floatY:        parseInt(wrap.dataset.floatY, 10)  || 24,
            storageKey:    wrap.dataset.storageKey     || 'bkdm-theme',
            attr:          wrap.dataset.attr           || 'data-theme',
            darkVal:       wrap.dataset.darkVal        || 'dark',
            lightVal:      wrap.dataset.lightVal       || 'light',
            defaultTheme:  wrap.dataset.default        || 'light',
            respectSystem: wrap.dataset.respectSystem  !== 'false',
            buttonSize:    parseInt(wrap.dataset.buttonSize, 10)   || 44,
            borderRadius:  parseInt(wrap.dataset.borderRadius, 10) || 50,
            duration:      reducedMotion() ? 0 : (parseInt(wrap.dataset.duration, 10) || 300),
            showIcon:      wrap.dataset.showIcon       !== 'false',
            showLabel:     wrap.dataset.showLabel      === 'true',
            lightIcon:     wrap.dataset.lightIcon      || '☀️',
            darkIcon:      wrap.dataset.darkIcon       || '🌙',
            lightLabel:    wrap.dataset.lightLabel     || 'Light',
            darkLabel:     wrap.dataset.darkLabel      || 'Dark',
            hoverScale:    wrap.dataset.hoverScale     !== 'false',
            shadow:        wrap.dataset.shadow         !== 'false',
            lightBg:       wrap.dataset.lightBg        || '#f3f4f6',
            lightColor:    wrap.dataset.lightColor     || '#111827',
            darkBg:        wrap.dataset.darkBg         || '#1f2937',
            darkColor:     wrap.dataset.darkColor      || '#f9fafb',
            trackLight:    wrap.dataset.trackLight     || '#d1d5db',
            trackDark:     wrap.dataset.trackDark      || '#4f46e5',
            thumb:         wrap.dataset.thumb          || '#ffffff',
        };

        // Set CSS vars for floating offsets
        wrap.style.setProperty('--bkdm-offset-x', cfg.floatX + 'px');
        wrap.style.setProperty('--bkdm-offset-y', cfg.floatY + 'px');

        // Determine initial theme
        var saved = null;
        try { saved = localStorage.getItem(cfg.storageKey); } catch (e) {}

        var sysDark = cfg.respectSystem
            ? window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches
            : false;

        var current = saved || (sysDark ? cfg.darkVal : cfg.lightVal);
        if (!saved && !sysDark) current = cfg.defaultTheme === 'dark' ? cfg.darkVal : cfg.lightVal;

        // Build button
        var btn = wrap.querySelector('.bkdm-btn');
        if (!btn) return;

        var thumbSize = Math.round(cfg.buttonSize * 0.5);

        btn.style.minWidth      = cfg.buttonSize + 'px';
        btn.style.height        = cfg.buttonSize + 'px';
        btn.style.padding       = '0 12px';
        btn.style.borderRadius  = cfg.borderRadius + 'px';
        btn.style.fontSize      = Math.round(cfg.buttonSize * 0.42) + 'px';
        btn.style.transition    = 'background ' + cfg.duration + 'ms ease, color ' + cfg.duration + 'ms ease, transform 0.15s ease';
        if (cfg.shadow) btn.style.boxShadow = '0 2px 8px rgba(0,0,0,0.18)';

        if (cfg.hoverScale) {
            btn.addEventListener('mouseenter', function () { btn.style.transform = 'scale(1.08)'; });
            btn.addEventListener('mouseleave', function () { btn.style.transform = 'scale(1)'; });
        }

        // Build inner HTML for switch style
        var iconEl, trackEl, thumbEl, labelEl;

        if (cfg.toggleStyle === 'switch') {
            btn.style.background  = 'none';
            btn.style.boxShadow   = 'none';
            btn.style.padding     = '0';
            btn.style.minWidth    = 'unset';
            btn.style.height      = 'unset';

            if (cfg.showIcon) {
                iconEl = document.createElement('span');
                iconEl.className = 'bkdm-icon';
                iconEl.style.fontSize = Math.round(cfg.buttonSize * 0.42) + 'px';
                iconEl.style.transition = 'opacity ' + cfg.duration + 'ms ease';
                btn.appendChild(iconEl);
            }

            trackEl = document.createElement('div');
            trackEl.className = 'bkdm-track';
            trackEl.style.width         = (cfg.buttonSize + 4) + 'px';
            trackEl.style.height        = Math.round(cfg.buttonSize * 0.6) + 'px';
            trackEl.style.borderRadius  = cfg.borderRadius + 'px';
            trackEl.style.transition    = 'background ' + cfg.duration + 'ms ease';

            thumbEl = document.createElement('div');
            thumbEl.className = 'bkdm-thumb';
            thumbSize = Math.round(cfg.buttonSize * 0.6) - 4;
            thumbEl.style.width      = thumbSize + 'px';
            thumbEl.style.height     = thumbSize + 'px';
            thumbEl.style.background = cfg.thumb;
            thumbEl.style.transition = 'transform ' + cfg.duration + 'ms ease';

            trackEl.appendChild(thumbEl);
            btn.appendChild(trackEl);

            if (cfg.showLabel) {
                labelEl = document.createElement('span');
                labelEl.className = 'bkdm-label';
                btn.appendChild(labelEl);
            }
        } else {
            // icon/button style
            if (cfg.showIcon) {
                iconEl = document.createElement('span');
                iconEl.className = 'bkdm-icon';
                iconEl.style.transition = 'opacity ' + cfg.duration + 'ms ease';
                btn.appendChild(iconEl);
            }
            if (cfg.showLabel) {
                labelEl = document.createElement('span');
                labelEl.className = 'bkdm-label';
                btn.appendChild(labelEl);
            }
        }

        function apply(theme) {
            var isDark = (theme === cfg.darkVal);
            current = theme;

            // Apply attribute to html element
            document.documentElement.setAttribute(cfg.attr.replace(/^data-/, ''), isDark ? cfg.darkVal : cfg.lightVal);
            // Also set the full data attribute
            document.documentElement.setAttribute(cfg.attr, isDark ? cfg.darkVal : cfg.lightVal);

            try { localStorage.setItem(cfg.storageKey, theme); } catch (e) {}

            btn.setAttribute('aria-pressed', String(isDark));

            if (iconEl)  iconEl.textContent  = isDark ? cfg.darkIcon  : cfg.lightIcon;
            if (labelEl) labelEl.textContent  = isDark ? cfg.darkLabel : cfg.lightLabel;

            if (cfg.toggleStyle === 'switch') {
                trackEl.style.background = isDark ? cfg.trackDark : cfg.trackLight;
                var travelX = trackEl.offsetWidth - thumbSize - 4;
                thumbEl.style.transform = isDark ? 'translateX(' + travelX + 'px)' : 'translateX(0)';
            } else {
                btn.style.background = isDark ? cfg.darkBg    : cfg.lightBg;
                btn.style.color      = isDark ? cfg.darkColor : cfg.lightColor;
            }
        }

        btn.addEventListener('click', function () {
            var next = (current === cfg.darkVal) ? cfg.lightVal : cfg.darkVal;
            apply(next);
        });

        // Initial paint (defer one tick so track has layout)
        requestAnimationFrame(function () { apply(current); });

        // Listen to system pref changes
        if (cfg.respectSystem && window.matchMedia) {
            window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', function (e) {
                try { if (localStorage.getItem(cfg.storageKey)) return; } catch (ex) {}
                apply(e.matches ? cfg.darkVal : cfg.lightVal);
            });
        }
    }

    function init() {
        var wraps = document.querySelectorAll('.bkdm-wrap[data-toggle-style]');
        wraps.forEach(function (wrap) { initToggle(wrap); });
    }

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }

}());

```
