# blockenberg/2.0.7/blocks/gradient-generator/frontend.js

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

- Page: https://pluginprobe.com/plugins/blockenberg/2.0.7/code/blocks/gradient-generator/frontend.js
- Raw: https://pluginprobe.com/plugins/blockenberg/2.0.7/raw/blocks/gradient-generator/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/gradient-generator/frontend.js#L10-L20`.

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

    var PRESETS = [
        { label:'Purple Dream', stops:'#6c3fb5 0%,#06b6d4 100%', type:'linear', angle:135 },
        { label:'Sunset',       stops:'#f97316 0%,#ef4444 50%,#a855f7 100%', type:'linear', angle:135 },
        { label:'Ocean',        stops:'#0ea5e9 0%,#10b981 100%', type:'linear', angle:135 },
        { label:'Midnight',     stops:'#1e1b4b 0%,#6c3fb5 50%,#0ea5e9 100%', type:'linear', angle:225 },
        { label:'Peach',        stops:'#f9a8d4 0%,#fed7aa 100%', type:'linear', angle:90 },
        { label:'Radial Burst', stops:'#fde68a 0%,#f97316 60%,#ef4444 100%', type:'radial', angle:135 },
        { label:'Forest',       stops:'#064e3b 0%,#10b981 100%', type:'linear', angle:135 },
        { label:'Rose Gold',    stops:'#fda4af 0%,#fb7185 40%,#f43f5e 100%', type:'linear', angle:135 }
    ];

    function parseStops(str) {
        return (str || '#6c3fb5 0%,#06b6d4 100%').split(',').map(function(s) {
            s = s.trim();
            var parts = s.match(/^(#[\w]+|rgba?\([^)]+\))\s+(\d+%?)$/);
            if (parts) return { color: parts[1], pos: parts[2] };
            return { color: s, pos: '' };
        });
    }

    function buildGradient(type, angle, stops) {
        var stopStr = stops.map(function(s) { return s.color + (s.pos ? ' ' + s.pos : ''); }).join(', ');
        if (type === 'radial') return 'radial-gradient(circle, ' + stopStr + ')';
        if (type === 'conic')  return 'conic-gradient(from ' + angle + 'deg, ' + stopStr + ')';
        return 'linear-gradient(' + angle + 'deg, ' + stopStr + ')';
    }

    function initGradientGenerator(app) {
        var opts;
        try { opts = JSON.parse(app.getAttribute('data-opts') || '{}'); } catch(e) { opts = {}; }

        function typoCssVarsForEl(typo, prefix, el) {
            if (!typo || typeof typo !== 'object') return;
            var map = {
                family:'font-family', weight:'font-weight', style:'font-style',
                decoration:'text-decoration', transform:'text-transform',
                sizeDesktop:'font-size-d', sizeTablet:'font-size-t', sizeMobile:'font-size-m',
                lineHeightDesktop:'line-height-d', lineHeightTablet:'line-height-t', lineHeightMobile:'line-height-m',
                letterSpacingDesktop:'letter-spacing-d', letterSpacingTablet:'letter-spacing-t', letterSpacingMobile:'letter-spacing-m',
                wordSpacingDesktop:'word-spacing-d', wordSpacingTablet:'word-spacing-t', wordSpacingMobile:'word-spacing-m'
            };
            Object.keys(map).forEach(function(k) {
                if (typo[k] !== undefined && typo[k] !== '') {
                    var v = typo[k];
                    if (['sizeDesktop','sizeTablet','sizeMobile'].indexOf(k) !== -1) v = v + (typo.sizeUnit || 'px');
                    else if (['lineHeightDesktop','lineHeightTablet','lineHeightMobile'].indexOf(k) !== -1) v = v + (typo.lineHeightUnit || '');
                    else if (['letterSpacingDesktop','letterSpacingTablet','letterSpacingMobile'].indexOf(k) !== -1) v = v + (typo.letterSpacingUnit || 'px');
                    else if (['wordSpacingDesktop','wordSpacingTablet','wordSpacingMobile'].indexOf(k) !== -1) v = v + (typo.wordSpacingUnit || 'px');
                    el.style.setProperty(prefix + map[k], String(v));
                }
            });
        }

        var accent        = opts.accentColor    || '#6c3fb5';
        var cardBg        = opts.cardBg         || '#ffffff';
        var controlsBg    = opts.controlsBg     || '#f9fafb';
        var controlsBorder= opts.controlsBorder || '#e5e7eb';
        var cssBg         = opts.cssBg          || '#1e1b4b';
        var cssColor      = opts.cssColor        || '#c4b5fd';
        var copyBg        = opts.copyBg          || accent;
        var copyColor     = opts.copyColor       || '#ffffff';
        var labelColor    = opts.labelColor      || '#374151';
        var titleColor    = opts.titleColor      || '';
        var subtitleColor = opts.subtitleColor   || '';
        var sectionBg     = opts.sectionBg       || '';

        var paddingTop    = (opts.paddingTop    != null ? opts.paddingTop    : 60) + 'px';
        var paddingBottom = (opts.paddingBottom != null ? opts.paddingBottom : 60) + 'px';
        var maxWidth      = (opts.maxWidth      || 600) + 'px';
        var cardRadius    = (opts.cardRadius    || 16)  + 'px';
        var previewRadius = (opts.previewRadius || 12)  + 'px';
        var previewHeight = (opts.previewHeight || 200) + 'px';
        var titleSize     = (opts.titleSize     || 28)  + 'px';

        var showPresets    = opts.showPresets    !== false;
        var showCssOutput  = opts.showCssOutput  !== false;
        var showTitle      = opts.showTitle      && opts.title;
        var showSubtitle   = opts.showSubtitle   && opts.subtitle;

        // State
        var state = {
            type:  opts.defaultType  || 'linear',
            angle: opts.defaultAngle != null ? opts.defaultAngle : 135,
            stops: parseStops(opts.defaultStops)
        };

        // Build initial HTML
        app.style.paddingTop    = paddingTop;
        app.style.paddingBottom = paddingBottom;
        if (sectionBg) app.style.background = sectionBg;

        typoCssVarsForEl(opts.typoTitle, '--bkbg-gg-tt-', app);
        typoCssVarsForEl(opts.typoBody,  '--bkbg-gg-bd-', app);

        var wrap = document.createElement('div');
        wrap.className = 'bkbg-gg-wrap';
        wrap.style.cssText = 'background:' + cardBg + ';border-radius:' + cardRadius + ';max-width:' + maxWidth;
        app.appendChild(wrap);

        // Header
        if (showTitle || showSubtitle) {
            var header = document.createElement('div');
            header.className = 'bkbg-gg-header';
            if (showTitle) {
                var h = document.createElement('div');
                h.className = 'bkbg-gg-title';
                h.style.cssText = (titleColor ? 'color:' + titleColor : '');
                h.textContent = opts.title;
                header.appendChild(h);
            }
            if (showSubtitle) {
                var sub = document.createElement('div');
                sub.className = 'bkbg-gg-subtitle';
                if (subtitleColor) sub.style.color = subtitleColor;
                sub.textContent = opts.subtitle;
                header.appendChild(sub);
            }
            wrap.appendChild(header);
        }

        // Preview swatch
        var preview = document.createElement('div');
        preview.className = 'bkbg-gg-preview';
        preview.style.height = previewHeight;
        preview.style.borderRadius = previewRadius;
        wrap.appendChild(preview);

        // Controls box
        var controls = document.createElement('div');
        controls.className = 'bkbg-gg-controls';
        controls.style.cssText = 'background:' + controlsBg + ';border:1.5px solid ' + controlsBorder;
        wrap.appendChild(controls);

        // Type + angle row
        var typeRow = document.createElement('div');
        typeRow.className = 'bkbg-gg-type-row';
        controls.appendChild(typeRow);

        var typeGroup = document.createElement('div');
        var typeLabel = document.createElement('label');
        typeLabel.className = 'bkbg-gg-label';
        typeLabel.style.color = labelColor;
        typeLabel.textContent = 'Type';
        var typeSelect = document.createElement('select');
        typeSelect.className = 'bkbg-gg-select';
        typeSelect.style.cssText = 'border:1.5px solid ' + controlsBorder;
        ['linear','radial','conic'].forEach(function(t) {
            var o = document.createElement('option');
            o.value = t; o.textContent = t.charAt(0).toUpperCase() + t.slice(1);
            typeSelect.appendChild(o);
        });
        typeSelect.value = state.type;
        typeGroup.appendChild(typeLabel);
        typeGroup.appendChild(typeSelect);
        typeRow.appendChild(typeGroup);

        var angleGroup = document.createElement('div');
        angleGroup.id = 'bkbg-gg-angle-group';
        var angleLabel = document.createElement('label');
        angleLabel.className = 'bkbg-gg-label';
        angleLabel.style.color = labelColor;
        angleLabel.textContent = 'Angle';
        var angleRow = document.createElement('div');
        angleRow.className = 'bkbg-gg-angle-row';
        var angleSlider = document.createElement('input');
        angleSlider.type = 'range'; angleSlider.min = 0; angleSlider.max = 360; angleSlider.step = 5;
        angleSlider.value = state.angle;
        var angleVal = document.createElement('span');
        angleVal.className = 'bkbg-gg-angle-val';
        angleVal.textContent = state.angle + '°';
        angleRow.appendChild(angleSlider);
        angleRow.appendChild(angleVal);
        angleGroup.appendChild(angleLabel);
        angleGroup.appendChild(angleRow);
        typeRow.appendChild(angleGroup);
        if (state.type === 'radial') angleGroup.style.display = 'none';

        // Stops container
        var stopsContainer = document.createElement('div');
        stopsContainer.className = 'bkbg-gg-stops';
        controls.appendChild(stopsContainer);

        function createStopRow(idx) {
            var row = document.createElement('div');
            row.className = 'bkbg-gg-stop-row';
            row.dataset.idx = idx;

            var swatch = document.createElement('input');
            swatch.type = 'color';
            swatch.className = 'bkbg-gg-color-swatch';
            swatch.style.cssText = 'background:' + state.stops[idx].color;
            swatch.value = state.stops[idx].color;

            var colorText = document.createElement('input');
            colorText.type = 'text';
            colorText.className = 'bkbg-gg-input-text bkbg-gg-input-color';
            colorText.style.cssText = 'border:1.5px solid ' + controlsBorder;
            colorText.value = state.stops[idx].color;
            colorText.placeholder = '#rrggbb';

            var posInput = document.createElement('input');
            posInput.type = 'text';
            posInput.className = 'bkbg-gg-input-text bkbg-gg-input-pos';
            posInput.style.cssText = 'border:1.5px solid ' + controlsBorder;
            posInput.value = state.stops[idx].pos;
            posInput.placeholder = '0%';

            var removeBtn = document.createElement('button');
            removeBtn.className = 'bkbg-gg-btn-remove';
            removeBtn.textContent = '×';
            removeBtn.disabled = state.stops.length <= 2;

            swatch.addEventListener('input', function() {
                state.stops[idx].color = swatch.value;
                colorText.value = swatch.value;
                refresh();
            });
            colorText.addEventListener('input', function() {
                state.stops[idx].color = colorText.value;
                if (/^#[0-9a-fA-F]{6}$/.test(colorText.value)) swatch.value = colorText.value;
                refresh();
            });
            posInput.addEventListener('input', function() {
                state.stops[idx].pos = posInput.value;
                refresh();
            });
            removeBtn.addEventListener('click', function() {
                if (state.stops.length <= 2) return;
                state.stops.splice(idx, 1);
                renderStops();
                refresh();
            });

            row.appendChild(swatch);
            row.appendChild(colorText);
            row.appendChild(posInput);
            row.appendChild(removeBtn);
            return row;
        }

        function renderStops() {
            stopsContainer.innerHTML = '';
            state.stops.forEach(function(_, i) {
                stopsContainer.appendChild(createStopRow(i));
            });
        }
        renderStops();

        // Add stop button
        var addBtn = document.createElement('button');
        addBtn.className = 'bkbg-gg-btn-add';
        addBtn.style.cssText = 'color:' + accent + ';border-color:' + controlsBorder;
        addBtn.textContent = '+ Add Color Stop';
        addBtn.addEventListener('click', function() {
            if (state.stops.length >= 5) return;
            state.stops.push({ color: '#ffffff', pos: '100%' });
            renderStops();
            refresh();
        });
        controls.appendChild(addBtn);

        // Presets
        if (showPresets) {
            var presetsSection = document.createElement('div');
            presetsSection.className = 'bkbg-gg-presets-section';
            var presetsHdr = document.createElement('div');
            presetsHdr.className = 'bkbg-gg-presets-label';
            presetsHdr.style.color = labelColor;
            presetsHdr.textContent = 'Presets';
            presetsSection.appendChild(presetsHdr);
            var presetsGrid = document.createElement('div');
            presetsGrid.className = 'bkbg-gg-presets-grid';
            PRESETS.forEach(function(p) {
                var btn = document.createElement('button');
                btn.className = 'bkbg-gg-preset-btn';
                var sw = document.createElement('div');
                sw.className = 'bkbg-gg-preset-swatch';
                sw.style.background = buildGradient(p.type, p.angle, parseStops(p.stops));
                var nm = document.createElement('span');
                nm.className = 'bkbg-gg-preset-name';
                nm.textContent = p.label;
                btn.appendChild(sw);
                btn.appendChild(nm);
                btn.addEventListener('click', function() {
                    state.stops = parseStops(p.stops);
                    state.type  = p.type;
                    state.angle = p.angle;
                    typeSelect.value = p.type;
                    angleSlider.value = p.angle;
                    angleVal.textContent = p.angle + '°';
                    angleGroup.style.display = (p.type === 'radial') ? 'none' : '';
                    renderStops();
                    refresh();
                });
                presetsGrid.appendChild(btn);
            });
            presetsSection.appendChild(presetsGrid);
            wrap.appendChild(presetsSection);
        }

        // CSS output
        var cssCode, copyBtn;
        if (showCssOutput) {
            var cssSection = document.createElement('div');
            cssSection.className = 'bkbg-gg-css-section';
            var cssBlock = document.createElement('div');
            cssBlock.className = 'bkbg-gg-css-block';
            cssBlock.style.cssText = 'background:' + cssBg + ';color:' + cssColor;
            cssCode = document.createElement('span');
            cssBlock.appendChild(cssCode);
            copyBtn = document.createElement('button');
            copyBtn.className = 'bkbg-gg-copy-btn';
            copyBtn.style.cssText = 'background:' + copyBg + ';color:' + copyColor;
            copyBtn.textContent = 'Copy CSS';
            copyBtn.addEventListener('click', function() {
                var text = 'background: ' + buildGradient(state.type, state.angle, state.stops) + ';';
                try {
                    navigator.clipboard.writeText(text).then(function() {
                        copyBtn.textContent = '✓ Copied!';
                        copyBtn.style.background = '#10b981';
                        setTimeout(function() { copyBtn.textContent = 'Copy CSS'; copyBtn.style.background = copyBg; }, 1500);
                    });
                } catch(e) {}
            });
            cssSection.appendChild(cssBlock);
            cssSection.appendChild(copyBtn);
            wrap.appendChild(cssSection);
        }

        // Wire type and angle controls
        typeSelect.addEventListener('change', function() {
            state.type = typeSelect.value;
            angleGroup.style.display = (state.type === 'radial') ? 'none' : '';
            refresh();
        });
        angleSlider.addEventListener('input', function() {
            state.angle = parseInt(angleSlider.value);
            angleVal.textContent = state.angle + '°';
            refresh();
        });

        function refresh() {
            var g = buildGradient(state.type, state.angle, state.stops);
            preview.style.background = g;
            if (cssCode) cssCode.textContent = 'background: ' + g + ';';
        }

        refresh();
    }

    document.querySelectorAll('.bkbg-gg-app').forEach(initGradientGenerator);
})();

```
