PluginProbe
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor / 2.0.7
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor v2.0.7
2.0.13 2.0.12 2.0.11 2.0.10 2.0.9 trunk 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8
blockenberg / blocks / color-converter / frontend.js

frontend.js in Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor 2.0.7, at blocks/color-converter/frontend.js

269 lines 11.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 (function () {
2 'use strict';
3
4 /* ── Typography CSS-var helper ── */
5 var _typoKeys = {
6 family:'font-family', weight:'font-weight', style:'font-style',
7 transform:'text-transform', decoration:'text-decoration',
8 sizeDesktop:'font-size-d', sizeTablet:'font-size-t', sizeMobile:'font-size-m',
9 lineHeightDesktop:'line-height-d', lineHeightTablet:'line-height-t', lineHeightMobile:'line-height-m',
10 letterSpacingDesktop:'letter-spacing-d', letterSpacingTablet:'letter-spacing-t', letterSpacingMobile:'letter-spacing-m',
11 wordSpacingDesktop:'word-spacing-d', wordSpacingTablet:'word-spacing-t', wordSpacingMobile:'word-spacing-m'
12 };
13 var _typoUnits = { size:'sizeUnit', lineHeight:'lineHeightUnit', letterSpacing:'letterSpacingUnit', wordSpacing:'wordSpacingUnit' };
14 var _typoUnitDefaults = { size:'px', lineHeight:'', letterSpacing:'px', wordSpacing:'px' };
15 function typoCssVarsForEl(el, obj, prefix) {
16 if (!obj || typeof obj !== 'object') return;
17 Object.keys(_typoKeys).forEach(function (k) {
18 var v = obj[k]; if (v === undefined || v === '') return;
19 var prop = _typoKeys[k];
20 var base = k.replace(/Desktop|Tablet|Mobile/, '');
21 var uKey = _typoUnits[base];
22 if (uKey && typeof v === 'number') v = v + (obj[uKey] || _typoUnitDefaults[base] || '');
23 el.style.setProperty(prefix + prop, v);
24 });
25 }
26
27 function clamp(n, lo, hi) { return Math.max(lo, Math.min(hi, n)); }
28
29 function hexToRgb(hex) {
30 hex = String(hex || '').replace(/^#/, '');
31 if (hex.length === 3) hex = hex.split('').map(function(c){ return c+c; }).join('');
32 if (hex.length !== 6 || /[^0-9a-fA-F]/.test(hex)) return null;
33 return { r: parseInt(hex.slice(0,2),16), g: parseInt(hex.slice(2,4),16), b: parseInt(hex.slice(4,6),16) };
34 }
35
36 function rgbToHex(r,g,b) {
37 return '#' + [r,g,b].map(function(x){ return clamp(Math.round(x),0,255).toString(16).padStart(2,'0'); }).join('');
38 }
39
40 function rgbToHsl(r,g,b) {
41 r/=255; g/=255; b/=255;
42 var max=Math.max(r,g,b), min=Math.min(r,g,b), l=(max+min)/2, h=0, s=0;
43 if (max!==min) {
44 var d=max-min;
45 s = l>0.5 ? d/(2-max-min) : d/(max+min);
46 switch(max) {
47 case r: h=((g-b)/d + (g<b?6:0))/6; break;
48 case g: h=((b-r)/d + 2)/6; break;
49 default: h=((r-g)/d + 4)/6;
50 }
51 }
52 return { h: Math.round(h*360), s: Math.round(s*100), l: Math.round(l*100) };
53 }
54
55 function hslToRgb(h,s,l) {
56 s/=100; l/=100; h/=360;
57 function hue2rgb(p,q,t){ if(t<0)t+=1; if(t>1)t-=1; if(t<1/6)return p+(q-p)*6*t; if(t<1/2)return q; if(t<2/3)return p+(q-p)*(2/3-t)*6; return p; }
58 var r,g,b;
59 if (s===0) { r=g=b=l; } else {
60 var q2=l<0.5?l*(1+s):l+s-l*s, p2=2*l-q2;
61 r=hue2rgb(p2,q2,h+1/3); g=hue2rgb(p2,q2,h); b=hue2rgb(p2,q2,h-1/3);
62 }
63 return { r:Math.round(r*255), g:Math.round(g*255), b:Math.round(b*255) };
64 }
65
66 function initColorConverter(app) {
67 var opts = {};
68 try { opts = JSON.parse(app.getAttribute('data-opts') || '{}'); } catch(e) {}
69
70 var cardBg = opts.cardBg || '#ffffff';
71 var swatchBorder = opts.swatchBorder || '#e5e7eb';
72 var inputBorder = opts.inputBorderColor || '#e5e7eb';
73 var copyBg = opts.copyBg || '#f3f4f6';
74 var copyColor = opts.copyColor || '#374151';
75 var labelColor = opts.labelColor || '#374151';
76 var titleColor = opts.titleColor || '#1f2937';
77 var subtitleColor= opts.subtitleColor || '#6b7280';
78 var sectionBg = opts.sectionBg || '';
79 var maxWidth = opts.maxWidth || 540;
80 var cardRadius = opts.cardRadius || 16;
81 var inputRadius = opts.inputRadius || 8;
82 var titleSize = opts.titleSize || 28;
83 var swatchHeight = opts.swatchHeight || 120;
84 var padTop = opts.paddingTop || 60;
85 var padBot = opts.paddingBottom || 60;
86 var showTitle = opts.showTitle !== false;
87 var showSub = opts.showSubtitle !== false;
88 var showSwatch = opts.showSwatchLarge !== false;
89 var showCopy = opts.showCopyBtns !== false;
90
91 var currentHex = opts.defaultHex || '#6c3fb5';
92 if (!hexToRgb(currentHex)) currentHex = '#6c3fb5';
93
94 // Outer
95 app.style.fontFamily = '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
96 if (sectionBg) app.style.background = sectionBg;
97 app.style.paddingTop = padTop + 'px';
98 app.style.paddingBottom = padBot + 'px';
99
100 typoCssVarsForEl(app, opts.typoTitle, '--bkbg-ccv-tt-');
101 typoCssVarsForEl(app, opts.typoSubtitle, '--bkbg-ccv-st-');
102
103 var card = document.createElement('div');
104 card.className = 'bkbg-clr-card';
105 card.style.cssText = 'background:' + cardBg + ';border-radius:' + cardRadius + 'px;padding:36px 32px;max-width:' + maxWidth + 'px;margin:0 auto;';
106 app.appendChild(card);
107
108 // Header
109 if (showTitle && opts.title) {
110 var titleEl = document.createElement('div');
111 titleEl.className = 'bkbg-ccv-title';
112 titleEl.style.cssText = 'color:' + titleColor + ';margin-bottom:6px;';
113 titleEl.textContent = opts.title;
114 card.appendChild(titleEl);
115 }
116 if (showSub && opts.subtitle) {
117 var subEl = document.createElement('div');
118 subEl.className = 'bkbg-ccv-subtitle';
119 subEl.style.cssText = 'color:' + subtitleColor + ';margin-bottom:20px;';
120 subEl.textContent = opts.subtitle;
121 card.appendChild(subEl);
122 }
123
124 // Swatch
125 var swatch;
126 if (showSwatch) {
127 swatch = document.createElement('div');
128 swatch.className = 'bkbg-clr-swatch';
129 swatch.style.cssText = 'height:' + swatchHeight + 'px;border-radius:' + inputRadius + 'px;border:2px solid ' + swatchBorder + ';margin-bottom:24px;background:' + currentHex + ';';
130 card.appendChild(swatch);
131 }
132
133 function makeCopyBtn(getText) {
134 if (!showCopy) return null;
135 var btn = document.createElement('button');
136 btn.className = 'bkbg-clr-copy-btn';
137 btn.style.background = copyBg;
138 btn.style.color = copyColor;
139 btn.textContent = 'Copy';
140 btn.addEventListener('click', function() {
141 try { navigator.clipboard.writeText(getText()); } catch(e) {}
142 btn.textContent = 'Copied!';
143 btn.classList.add('copied');
144 setTimeout(function(){ btn.textContent = 'Copy'; btn.classList.remove('copied'); }, 1500);
145 });
146 return btn;
147 }
148
149 function makeInput(opts2) {
150 var inp = document.createElement('input');
151 inp.className = 'bkbg-clr-input';
152 inp.type = opts2.type || 'text';
153 if (opts2.min !== undefined) { inp.min = opts2.min; inp.max = opts2.max; }
154 inp.style.borderRadius = inputRadius + 'px';
155 inp.style.borderColor = inputBorder;
156 return inp;
157 }
158
159 function makeLabel(txt, isSmall) {
160 var lbl = document.createElement('label');
161 lbl.style.display = 'block';
162 lbl.style.fontWeight = '600';
163 lbl.style.color = labelColor;
164 lbl.style.marginBottom = '5px';
165 if (isSmall) {
166 lbl.style.fontSize = '11px';
167 } else {
168 lbl.style.fontSize = '12px';
169 lbl.style.textTransform = 'uppercase';
170 lbl.style.letterSpacing = '.04em';
171 }
172 lbl.textContent = txt;
173 return lbl;
174 }
175
176 var hexInput, rInp, gInp, bInp, hInp, sInp, lInp;
177
178 // HEX section
179 var hexSec = document.createElement('div');
180 hexSec.className = 'bkbg-clr-section';
181 hexSec.appendChild(makeLabel('HEX'));
182 hexInput = makeInput({ type: 'text' });
183 hexSec.appendChild(hexInput);
184 if (showCopy) hexSec.appendChild(makeCopyBtn(function(){ return hexInput.value; }));
185 card.appendChild(hexSec);
186
187 // RGB section
188 var rgbSec = document.createElement('div');
189 rgbSec.className = 'bkbg-clr-section';
190 rgbSec.appendChild(makeLabel('RGB'));
191 var rgbGrid = document.createElement('div');
192 rgbGrid.className = 'bkbg-clr-rgb-grid';
193 [['R', 'r'], ['G', 'g'], ['B', 'b']].forEach(function(pair) {
194 var col = document.createElement('div');
195 col.appendChild(makeLabel(pair[0], true));
196 var inp = makeInput({ type:'number', min:0, max:255 });
197 if (pair[1]==='r') rInp=inp;
198 else if (pair[1]==='g') gInp=inp;
199 else bInp=inp;
200 col.appendChild(inp);
201 rgbGrid.appendChild(col);
202 });
203 rgbSec.appendChild(rgbGrid);
204 if (showCopy) rgbSec.appendChild(makeCopyBtn(function(){ return 'rgb(' + rInp.value + ', ' + gInp.value + ', ' + bInp.value + ')'; }));
205 card.appendChild(rgbSec);
206
207 // HSL section
208 var hslSec = document.createElement('div');
209 hslSec.appendChild(makeLabel('HSL'));
210 var hslGrid = document.createElement('div');
211 hslGrid.className = 'bkbg-clr-rgb-grid';
212 [['', 'h', 360], ['S%', 's', 100], ['L%', 'l', 100]].forEach(function(t) {
213 var col = document.createElement('div');
214 col.appendChild(makeLabel(t[0], true));
215 var inp = makeInput({ type:'number', min:0, max:t[2] });
216 if (t[1]==='h') hInp=inp;
217 else if (t[1]==='s') sInp=inp;
218 else lInp=inp;
219 col.appendChild(inp);
220 hslGrid.appendChild(col);
221 });
222 hslSec.appendChild(hslGrid);
223 if (showCopy) hslSec.appendChild(makeCopyBtn(function(){ return 'hsl(' + hInp.value + ', ' + sInp.value + '%, ' + lInp.value + '%)'; }));
224 card.appendChild(hslSec);
225
226 var updating = false;
227
228 function applyHex(hex) {
229 if (updating) return;
230 var rgb = hexToRgb(hex); if (!rgb) return;
231 var hsl = rgbToHsl(rgb.r, rgb.g, rgb.b);
232 updating = true;
233 hexInput.value = hex;
234 rInp.value = rgb.r; gInp.value = rgb.g; bInp.value = rgb.b;
235 hInp.value = hsl.h; sInp.value = hsl.s; lInp.value = hsl.l;
236 if (swatch) swatch.style.background = hex;
237 updating = false;
238 }
239
240 hexInput.addEventListener('input', function() {
241 var v = hexInput.value.trim();
242 if (!v.startsWith('#')) v = '#' + v;
243 if (hexToRgb(v)) applyHex(v);
244 });
245
246 function fromRgb() {
247 if (updating) return;
248 var hex = rgbToHex(parseInt(rInp.value)||0, parseInt(gInp.value)||0, parseInt(bInp.value)||0);
249 applyHex(hex);
250 }
251 rInp.addEventListener('input', fromRgb);
252 gInp.addEventListener('input', fromRgb);
253 bInp.addEventListener('input', fromRgb);
254
255 function fromHsl() {
256 if (updating) return;
257 var rgb = hslToRgb(parseInt(hInp.value)||0, parseInt(sInp.value)||0, parseInt(lInp.value)||0);
258 applyHex(rgbToHex(rgb.r, rgb.g, rgb.b));
259 }
260 hInp.addEventListener('input', fromHsl);
261 sInp.addEventListener('input', fromHsl);
262 lInp.addEventListener('input', fromHsl);
263
264 applyHex(currentHex);
265 }
266
267 document.querySelectorAll('.bkbg-clr-app').forEach(initColorConverter);
268 })();
269