PluginProbe
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor / 2.0.13
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor v2.0.13
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 / qr-code / index.js

index.js in Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor 2.0.13, at blocks/qr-code/index.js

306 lines 15.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 ( function () {
2 var el = wp.element.createElement;
3 var __ = wp.i18n.__;
4 var useState = wp.element.useState;
5 var useEffect = wp.element.useEffect;
6 var useRef = wp.element.useRef;
7 var registerBlockType = wp.blocks.registerBlockType;
8 var InspectorControls = wp.blockEditor.InspectorControls;
9 var useBlockProps = wp.blockEditor.useBlockProps;
10 var PanelColorSettings = wp.blockEditor.PanelColorSettings;
11 var PanelBody = wp.components.PanelBody;
12 var ToggleControl = wp.components.ToggleControl;
13 var RangeControl = wp.components.RangeControl;
14 var SelectControl = wp.components.SelectControl;
15 var TextControl = wp.components.TextControl;
16 var Button = wp.components.Button;
17
18 var ALIGN_OPTIONS = [
19 { label: 'Left', value: 'left' },
20 { label: 'Center', value: 'center' },
21 { label: 'Right', value: 'right' },
22 ];
23 var ERROR_LEVELS = [
24 { label: 'Low (L — 7%)', value: 'L' },
25 { label: 'Medium (M — 15%)', value: 'M' },
26 { label: 'Quartile (Q — 25%)', value: 'Q' },
27 { label: 'High (H — 30%)', value: 'H' },
28 ];
29 var BORDER_STYLES = [
30 { label: 'Shadow', value: 'shadow' },
31 { label: 'Border', value: 'border' },
32 { label: 'None', value: 'none' },
33 ];
34
35 var _tc; function getTypoControl() { return _tc || (_tc = window.bkbgTypographyControl); }
36 var _tv; function getTypoCssVars() { return _tv || (_tv = window.bkbgTypoCssVars); }
37
38 /* ── QR render in editor ──────────────────────────────────────────────── */
39 function QRPreview(props) {
40 var a = props;
41 var containerRef = useRef(null);
42 var qrRef = useRef(null);
43
44 function renderQR() {
45 if (!containerRef.current) return;
46 if (typeof window.QRCode === 'undefined') return;
47 try {
48 if (qrRef.current) { qrRef.current.clear(); qrRef.current.makeCode(a.content); return; }
49 containerRef.current.innerHTML = '';
50 qrRef.current = new window.QRCode(containerRef.current, {
51 text: a.content || 'https://example.com',
52 width: a.size, height: a.size,
53 colorDark: a.fgColor,
54 colorLight: a.bgColor,
55 correctLevel: window.QRCode.CorrectLevel[a.errorLevel] || window.QRCode.CorrectLevel.M,
56 });
57 } catch (e) { /* ignore */ }
58 }
59
60 useEffect(function () {
61 if (typeof window.QRCode !== 'undefined') { renderQR(); return; }
62 var s = document.createElement('script');
63 s.src = 'https://cdnjs.cloudflare.com/ajax/libs/qrcodejs/1.0.0/qrcode.min.js';
64 s.onload = renderQR;
65 document.head.appendChild(s);
66 }, []);
67
68 useEffect(renderQR, [a.content, a.size, a.fgColor, a.bgColor, a.errorLevel]);
69
70 var boxStyle = {
71 display: 'inline-block',
72 background: a.cardBg,
73 padding: a.cardPadding + 'px',
74 borderRadius: a.borderRadius + 'px',
75 boxShadow: a.borderStyle === 'shadow' ? '0 4px 16px rgba(0,0,0,0.10)' : 'none',
76 border: a.borderStyle === 'border' ? '1px solid ' + a.borderColor : 'none',
77 textAlign: 'center',
78 };
79
80 return el('div', { style: { textAlign: a.align } },
81 el('div', { style: boxStyle },
82 el('div', { ref: containerRef }),
83 a.showCaption && a.caption && el('p', {
84 className: 'bkqr-caption',
85 style: { margin: '10px 0 0', color: a.captionColor }
86 }, a.caption),
87 a.downloadable && el('button', {
88 style: { display: 'block', margin: '10px auto 0', fontSize: '12px', color: '#9ca3af', background: 'none', border: '1px solid #e5e7eb', borderRadius: '6px', padding: '4px 10px', cursor: 'default', opacity: 0.7 },
89 disabled: true,
90 }, a.downloadLabel),
91 )
92 );
93 }
94
95 var v1Attributes = {
96 content: { type: 'string', default: 'https://example.com' },
97 size: { type: 'number', default: 200 },
98 fgColor: { type: 'string', default: '#1f2937' },
99 bgColor: { type: 'string', default: '#ffffff' },
100 errorLevel: { type: 'string', default: 'M' },
101 caption: { type: 'string', default: '' },
102 showCaption: { type: 'boolean', default: false },
103 captionColor: { type: 'string', default: '#6b7280' },
104 captionSize: { type: 'number', default: 13 },
105 align: { type: 'string', default: 'center' },
106 cardBg: { type: 'string', default: '#ffffff' },
107 cardPadding: { type: 'number', default: 20 },
108 borderRadius: { type: 'number', default: 12 },
109 borderStyle: { type: 'string', default: 'shadow' },
110 borderColor: { type: 'string', default: '#e5e7eb' },
111 downloadable: { type: 'boolean', default: true },
112 downloadLabel: { type: 'string', default: 'Download QR' },
113 captionFontWeight: { type: 'number', default: 400 },
114 captionLineHeight: { type: 'number', default: 1.4 }
115 };
116
117 registerBlockType('blockenberg/qr-code', {
118 edit: function (props) {
119 var a = props.attributes;
120 var set = props.setAttributes;
121 var TC = getTypoControl();
122 var blockProps = useBlockProps((function () {
123 var _tv = getTypoCssVars();
124 var s = { textAlign: a.align };
125 if (_tv) {
126 Object.assign(s, _tv(a.captionTypo || {}, '--bkqr-cap-'));
127 }
128 return { style: s };
129 })());
130
131 return el('div', blockProps,
132 el(InspectorControls, null,
133 el(PanelBody, { title: __('QR Code Content', 'blockenberg'), initialOpen: true },
134 el(TextControl, {
135 label: __('URL or Text to Encode', 'blockenberg'),
136 value: a.content,
137 onChange: function (v) { set({ content: v }); },
138 help: __('Paste any URL, phone number, email or plain text.', 'blockenberg')
139 }),
140 el(SelectControl, {
141 label: __('Error Correction', 'blockenberg'),
142 value: a.errorLevel,
143 options: ERROR_LEVELS,
144 onChange: function (v) { set({ errorLevel: v }); },
145 help: __('Higher = more data redundancy, larger QR.', 'blockenberg')
146 }),
147 ),
148 el(PanelBody, { title: __('Size & Layout', 'blockenberg'), initialOpen: false },
149 el(RangeControl, {
150 label: __('QR Size (px)', 'blockenberg'),
151 value: a.size, min: 80, max: 500,
152 onChange: function (v) { set({ size: v }); }
153 }),
154 el(SelectControl, {
155 label: __('Alignment', 'blockenberg'),
156 value: a.align,
157 options: ALIGN_OPTIONS,
158 onChange: function (v) { set({ align: v }); }
159 }),
160 el(RangeControl, {
161 label: __('Card Padding (px)', 'blockenberg'),
162 value: a.cardPadding, min: 0, max: 60,
163 onChange: function (v) { set({ cardPadding: v }); }
164 }),
165 el(RangeControl, {
166 label: __('Border Radius (px)', 'blockenberg'),
167 value: a.borderRadius, min: 0, max: 32,
168 onChange: function (v) { set({ borderRadius: v }); }
169 }),
170 el(SelectControl, {
171 label: __('Border Style', 'blockenberg'),
172 value: a.borderStyle,
173 options: BORDER_STYLES,
174 onChange: function (v) { set({ borderStyle: v }); }
175 }),
176 ),
177 el(PanelBody, { title: __('Caption & Download', 'blockenberg'), initialOpen: false },
178 el(ToggleControl, {
179 label: __('Show Caption', 'blockenberg'),
180 checked: a.showCaption,
181 onChange: function (v) { set({ showCaption: v }); },
182 __nextHasNoMarginBottom: true
183 }),
184 a.showCaption && el(TextControl, {
185 label: __('Caption Text', 'blockenberg'),
186 value: a.caption,
187 onChange: function (v) { set({ caption: v }); }
188 }),
189 el(ToggleControl, {
190 label: __('Show Download Button', 'blockenberg'),
191 checked: a.downloadable,
192 onChange: function (v) { set({ downloadable: v }); },
193 __nextHasNoMarginBottom: true
194 }),
195 a.downloadable && el(TextControl, {
196 label: __('Download Button Label', 'blockenberg'),
197 value: a.downloadLabel,
198 onChange: function (v) { set({ downloadLabel: v }); }
199 }),
200 ),
201
202 el( PanelBody, { title: __( 'Typography', 'blockenberg' ), initialOpen: false },
203 TC && el(TC, { label: __('Caption', 'blockenberg'), value: a.captionTypo || {}, onChange: function(v) { set({ captionTypo: v }); } })
204 ),
205 el(PanelColorSettings, {
206 title: __('Colors', 'blockenberg'),
207 initialOpen: false,
208 colorSettings: [
209 { label: __('QR Foreground', 'blockenberg'), value: a.fgColor, onChange: function (v) { set({ fgColor: v || '#1f2937' }); } },
210 { label: __('QR Background', 'blockenberg'), value: a.bgColor, onChange: function (v) { set({ bgColor: v || '#ffffff' }); } },
211 { label: __('Card Background', 'blockenberg'), value: a.cardBg, onChange: function (v) { set({ cardBg: v || '#ffffff' }); } },
212 { label: __('Border Color', 'blockenberg'), value: a.borderColor, onChange: function (v) { set({ borderColor: v || '#e5e7eb' }); } },
213 { label: __('Caption Color', 'blockenberg'), value: a.captionColor, onChange: function (v) { set({ captionColor: v || '#6b7280' }); } },
214 ]
215 }),
216 ),
217 el(QRPreview, a)
218 );
219 },
220
221 save: function (props) {
222 var a = props.attributes;
223 var boxStyle = {
224 display: 'inline-block',
225 background: a.cardBg,
226 padding: a.cardPadding + 'px',
227 borderRadius: a.borderRadius + 'px',
228 boxShadow: a.borderStyle === 'shadow' ? '0 4px 16px rgba(0,0,0,0.10)' : 'none',
229 border: a.borderStyle === 'border' ? '1px solid ' + a.borderColor : 'none',
230 textAlign: 'center',
231 };
232 return el('div', {
233 className: 'bkqr-wrap',
234 style: (function () {
235 var _tv = getTypoCssVars();
236 var s = { textAlign: a.align };
237 if (_tv) {
238 Object.assign(s, _tv(a.captionTypo || {}, '--bkqr-cap-'));
239 }
240 return s;
241 })()
242 },
243 el('div', {
244 className: 'bkqr-box',
245 style: boxStyle,
246 'data-content': a.content,
247 'data-size': a.size,
248 'data-fg': a.fgColor,
249 'data-bg': a.bgColor,
250 'data-level': a.errorLevel,
251 },
252 el('div', { className: 'bkqr-canvas' }),
253 a.showCaption && a.caption && el('p', {
254 className: 'bkqr-caption',
255 style: { margin: '10px 0 0', color: a.captionColor }
256 }, a.caption),
257 a.downloadable && el('button', {
258 className: 'bkqr-download',
259 style: { display: 'block', margin: '10px auto 0', fontSize: '12px', color: '#6b7280', background: 'none', border: '1px solid #d1d5db', borderRadius: '6px', padding: '5px 12px', cursor: 'pointer', fontFamily: 'inherit' }
260 }, a.downloadLabel),
261 )
262 );
263 },
264
265 deprecated: [{
266 attributes: v1Attributes,
267 save: function (props) {
268 var a = props.attributes;
269 var boxStyle = {
270 display: 'inline-block',
271 background: a.cardBg,
272 padding: a.cardPadding + 'px',
273 borderRadius: a.borderRadius + 'px',
274 boxShadow: a.borderStyle === 'shadow' ? '0 4px 16px rgba(0,0,0,0.10)' : 'none',
275 border: a.borderStyle === 'border' ? '1px solid ' + a.borderColor : 'none',
276 textAlign: 'center',
277 };
278 return el('div', {
279 className: 'bkqr-wrap',
280 style: { textAlign: a.align }
281 },
282 el('div', {
283 className: 'bkqr-box',
284 style: boxStyle,
285 'data-content': a.content,
286 'data-size': a.size,
287 'data-fg': a.fgColor,
288 'data-bg': a.bgColor,
289 'data-level': a.errorLevel,
290 },
291 el('div', { className: 'bkqr-canvas' }),
292 a.showCaption && a.caption && el('p', {
293 className: 'bkqr-caption',
294 style: { margin: '10px 0 0', color: a.captionColor, fontSize: a.captionSize + 'px', fontWeight: (a.captionFontWeight || 400), lineHeight: (a.captionLineHeight || 1.4) }
295 }, a.caption),
296 a.downloadable && el('button', {
297 className: 'bkqr-download',
298 style: { display: 'block', margin: '10px auto 0', fontSize: '12px', color: '#6b7280', background: 'none', border: '1px solid #d1d5db', borderRadius: '6px', padding: '5px 12px', cursor: 'pointer', fontFamily: 'inherit' }
299 }, a.downloadLabel),
300 )
301 );
302 }
303 }],
304 });
305 }() );
306