PluginProbe
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor / 2.0.14
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor v2.0.14
2.0.14 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 / print-button / index.js

index.js in Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor 2.0.14, at blocks/print-button/index.js

420 lines 12.8 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 var el = wp.element.createElement;
5 var Fragment = wp.element.Fragment;
6 var __ = wp.i18n.__;
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 TextControl = wp.components.TextControl;
13 var ToggleControl = wp.components.ToggleControl;
14 var SelectControl = wp.components.SelectControl;
15 var RangeControl = wp.components.RangeControl;
16
17 var _tcCache;
18 var _tvCache;
19 function getTypographyControl() {
20 return _tcCache || ( _tcCache = window.bkbgTypographyControl );
21 }
22 function typoCssVars( obj, prefix ) {
23 var fn = _tvCache || ( _tvCache = window.bkbgTypoCssVars );
24 return fn ? fn( obj, prefix ) : {};
25 }
26 function IP() {
27 return window.bkbgIconPicker;
28 }
29
30 function floatingPosStyle( position, offsetX, offsetY ) {
31 var style = {};
32 var y = ( offsetY || 24 ) + 'px';
33 var x = ( offsetX || 24 ) + 'px';
34 if ( position === 'bottom-left' ) {
35 style.bottom = y;
36 style.left = x;
37 } else if ( position === 'bottom-center' ) {
38 style.bottom = y;
39 style.left = '50%';
40 style.transform = 'translateX(-50%)';
41 } else if ( position === 'top-right' ) {
42 style.top = y;
43 style.right = x;
44 } else if ( position === 'top-left' ) {
45 style.top = y;
46 style.left = x;
47 } else {
48 style.bottom = y;
49 style.right = x;
50 }
51 return style;
52 }
53
54 function buildBtnStyle( a ) {
55 return {
56 display: 'inline-flex',
57 alignItems: 'center',
58 justifyContent: 'center',
59 gap: '8px',
60 padding: ( a.paddingV || 12 ) + 'px ' + ( a.paddingH || 20 ) + 'px',
61 background: a.bgColor || '#1e293b',
62 color: a.textColor || '#ffffff',
63 borderRadius: ( a.borderRadius || 0 ) + 'px',
64 borderStyle: 'solid',
65 borderWidth: ( a.borderWidth || 0 ) + 'px',
66 borderColor: a.borderColor || a.bgColor || '#1e293b',
67 boxShadow: a.shadow ? '0 4px 16px rgba(15, 23, 42, 0.18)' : 'none',
68 cursor: 'pointer',
69 // Typography (family / line-height / decoration / etc.) comes from
70 // CSS vars on the wrap — do not set font* here or they override typo.
71 '--bkbg-prb-hover-bg': a.hoverBg || '#0f172a',
72 '--bkbg-prb-hover-color': a.hoverColor || '#ffffff'
73 };
74 }
75
76 function renderIcon( a, forSave ) {
77 if ( ! a.showIcon ) {
78 return null;
79 }
80
81 var style = {
82 fontSize: ( a.iconSize || 18 ) + 'px',
83 lineHeight: 1,
84 display: 'inline-flex',
85 alignItems: 'center',
86 justifyContent: 'center',
87 flexShrink: 0
88 };
89 var type = a.iconType || 'dashicon';
90 var picker = IP();
91
92 if ( ! picker || type === 'custom-char' || type === 'none' ) {
93 if ( type === 'none' ) {
94 return null;
95 }
96 return el( 'span', {
97 className: 'bkbg-prb-icon',
98 style: style,
99 'aria-hidden': 'true'
100 }, a.icon || '🖨' );
101 }
102
103 var builder = forSave ? picker.buildSaveIcon : picker.buildEditorIcon;
104 return el( 'span', {
105 className: 'bkbg-prb-icon',
106 style: style,
107 'aria-hidden': 'true'
108 }, builder( type, a.icon, a.iconDashicon, a.iconImageUrl, a.iconDashiconColor || '' ) );
109 }
110
111 function renderButtonChildren( a, forSave ) {
112 var iconEl = renderIcon( a, forSave );
113 var labelEl = a.showLabel && a.label
114 ? el( 'span', { className: 'bkbg-prb-label' }, a.label )
115 : null;
116 return a.iconPosition === 'right'
117 ? [ labelEl, iconEl ]
118 : [ iconEl, labelEl ];
119 }
120
121 registerBlockType( 'blockenberg/print-button', {
122 edit: function ( props ) {
123 var a = props.attributes;
124 var setAttributes = props.setAttributes;
125 var isFloating = a.layout === 'floating';
126 var TypographyControl = getTypographyControl();
127 var picker = IP();
128
129 var wrapStyle = Object.assign(
130 {},
131 typoCssVars( a.typoBtn || {}, '--bkbg-prb-btn-' ),
132 isFloating
133 ? {
134 minHeight: '96px',
135 background: '#f1f5f9',
136 borderRadius: '12px',
137 display: 'flex',
138 flexDirection: 'column',
139 alignItems: 'center',
140 justifyContent: 'center',
141 padding: '24px'
142 }
143 : {
144 textAlign: a.alignBtn || 'left',
145 padding: '8px 0'
146 }
147 );
148
149 var blockProps = useBlockProps( {
150 className: 'bkbg-prb-editor' + ( isFloating ? ' bkbg-prb-editor--floating' : '' ),
151 style: wrapStyle
152 } );
153
154 return el(
155 Fragment,
156 null,
157 el(
158 InspectorControls,
159 null,
160 el(
161 PanelBody,
162 { title: __( 'Content', 'blockenberg' ), initialOpen: true },
163 el( ToggleControl, {
164 label: __( 'Show label', 'blockenberg' ),
165 checked: !! a.showLabel,
166 onChange: function ( v ) { setAttributes( { showLabel: v } ); },
167 __nextHasNoMarginBottom: true
168 } ),
169 a.showLabel && el( TextControl, {
170 label: __( 'Button label', 'blockenberg' ),
171 value: a.label,
172 onChange: function ( v ) { setAttributes( { label: v } ); },
173 __nextHasNoMarginBottom: true
174 } ),
175 el( TextControl, {
176 label: __( 'ARIA label (optional)', 'blockenberg' ),
177 value: a.ariaLabel || '',
178 help: __( 'Overrides the accessible name when the visible label is empty.', 'blockenberg' ),
179 onChange: function ( v ) { setAttributes( { ariaLabel: v } ); },
180 __nextHasNoMarginBottom: true
181 } )
182 ),
183 el(
184 PanelBody,
185 { title: __( 'Icon', 'blockenberg' ), initialOpen: true },
186 el( ToggleControl, {
187 label: __( 'Show icon', 'blockenberg' ),
188 checked: !! a.showIcon,
189 onChange: function ( v ) { setAttributes( { showIcon: v } ); },
190 __nextHasNoMarginBottom: true
191 } ),
192 a.showIcon && picker && el(
193 picker.IconPickerControl,
194 picker.iconPickerProps( a, setAttributes )
195 ),
196 a.showIcon && ! picker && el(
197 'p',
198 { style: { color: '#999', fontSize: '12px' } },
199 __( 'Icon picker loading…', 'blockenberg' )
200 ),
201 a.showIcon && el( SelectControl, {
202 label: __( 'Icon position', 'blockenberg' ),
203 value: a.iconPosition,
204 options: [
205 { label: __( 'Left', 'blockenberg' ), value: 'left' },
206 { label: __( 'Right', 'blockenberg' ), value: 'right' }
207 ],
208 onChange: function ( v ) { setAttributes( { iconPosition: v } ); },
209 __nextHasNoMarginBottom: true
210 } ),
211 a.showIcon && el( RangeControl, {
212 label: __( 'Icon size (px)', 'blockenberg' ),
213 value: a.iconSize,
214 min: 12,
215 max: 40,
216 onChange: function ( v ) { setAttributes( { iconSize: v } ); }
217 } )
218 ),
219 el(
220 PanelBody,
221 { title: __( 'Layout', 'blockenberg' ), initialOpen: false },
222 el( SelectControl, {
223 label: __( 'Placement', 'blockenberg' ),
224 value: a.layout,
225 options: [
226 { label: __( 'Inline (in content)', 'blockenberg' ), value: 'inline' },
227 { label: __( 'Floating (fixed)', 'blockenberg' ), value: 'floating' }
228 ],
229 onChange: function ( v ) { setAttributes( { layout: v } ); },
230 __nextHasNoMarginBottom: true
231 } ),
232 ! isFloating && el( SelectControl, {
233 label: __( 'Alignment', 'blockenberg' ),
234 value: a.alignBtn,
235 options: [
236 { label: __( 'Left', 'blockenberg' ), value: 'left' },
237 { label: __( 'Center', 'blockenberg' ), value: 'center' },
238 { label: __( 'Right', 'blockenberg' ), value: 'right' }
239 ],
240 onChange: function ( v ) { setAttributes( { alignBtn: v } ); },
241 __nextHasNoMarginBottom: true
242 } ),
243 isFloating && el( SelectControl, {
244 label: __( 'Screen position', 'blockenberg' ),
245 value: a.position,
246 options: [
247 { label: __( 'Bottom right', 'blockenberg' ), value: 'bottom-right' },
248 { label: __( 'Bottom left', 'blockenberg' ), value: 'bottom-left' },
249 { label: __( 'Bottom center', 'blockenberg' ), value: 'bottom-center' },
250 { label: __( 'Top right', 'blockenberg' ), value: 'top-right' },
251 { label: __( 'Top left', 'blockenberg' ), value: 'top-left' }
252 ],
253 onChange: function ( v ) { setAttributes( { position: v } ); },
254 __nextHasNoMarginBottom: true
255 } ),
256 isFloating && a.position !== 'bottom-center' && el( RangeControl, {
257 label: __( 'Horizontal offset (px)', 'blockenberg' ),
258 value: a.offsetX,
259 min: 8,
260 max: 120,
261 onChange: function ( v ) { setAttributes( { offsetX: v } ); }
262 } ),
263 isFloating && el( RangeControl, {
264 label: __( 'Vertical offset (px)', 'blockenberg' ),
265 value: a.offsetY,
266 min: 8,
267 max: 120,
268 onChange: function ( v ) { setAttributes( { offsetY: v } ); }
269 } ),
270 isFloating && el( RangeControl, {
271 label: __( 'Z-index', 'blockenberg' ),
272 value: a.zIndex,
273 min: 100,
274 max: 99999,
275 onChange: function ( v ) { setAttributes( { zIndex: v } ); }
276 } )
277 ),
278 el(
279 PanelBody,
280 { title: __( 'Size & shape', 'blockenberg' ), initialOpen: false },
281 el( RangeControl, {
282 label: __( 'Horizontal padding (px)', 'blockenberg' ),
283 value: a.paddingH,
284 min: 8,
285 max: 64,
286 onChange: function ( v ) { setAttributes( { paddingH: v } ); }
287 } ),
288 el( RangeControl, {
289 label: __( 'Vertical padding (px)', 'blockenberg' ),
290 value: a.paddingV,
291 min: 4,
292 max: 40,
293 onChange: function ( v ) { setAttributes( { paddingV: v } ); }
294 } ),
295 el( RangeControl, {
296 label: __( 'Border radius (px)', 'blockenberg' ),
297 value: a.borderRadius,
298 min: 0,
299 max: 999,
300 onChange: function ( v ) { setAttributes( { borderRadius: v } ); }
301 } ),
302 el( RangeControl, {
303 label: __( 'Border width (px)', 'blockenberg' ),
304 value: a.borderWidth,
305 min: 0,
306 max: 6,
307 onChange: function ( v ) { setAttributes( { borderWidth: v } ); }
308 } ),
309 el( ToggleControl, {
310 label: __( 'Drop shadow', 'blockenberg' ),
311 checked: !! a.shadow,
312 onChange: function ( v ) { setAttributes( { shadow: v } ); },
313 __nextHasNoMarginBottom: true
314 } )
315 ),
316 el(
317 PanelBody,
318 { title: __( 'Typography', 'blockenberg' ), initialOpen: false },
319 TypographyControl
320 ? el( TypographyControl, {
321 label: __( 'Button text', 'blockenberg' ),
322 value: a.typoBtn || {},
323 onChange: function ( v ) { setAttributes( { typoBtn: v } ); }
324 } )
325 : el( 'p', { style: { color: '#999', fontSize: '12px' } }, __( 'Typography control loading…', 'blockenberg' ) )
326 ),
327 el( PanelColorSettings, {
328 title: __( 'Colors', 'blockenberg' ),
329 initialOpen: false,
330 colorSettings: [
331 {
332 label: __( 'Background', 'blockenberg' ),
333 value: a.bgColor,
334 onChange: function ( v ) { setAttributes( { bgColor: v || '#1e293b' } ); }
335 },
336 {
337 label: __( 'Text / icon', 'blockenberg' ),
338 value: a.textColor,
339 onChange: function ( v ) { setAttributes( { textColor: v || '#ffffff' } ); }
340 },
341 {
342 label: __( 'Hover background', 'blockenberg' ),
343 value: a.hoverBg,
344 onChange: function ( v ) { setAttributes( { hoverBg: v || '#0f172a' } ); }
345 },
346 {
347 label: __( 'Hover text / icon', 'blockenberg' ),
348 value: a.hoverColor,
349 onChange: function ( v ) { setAttributes( { hoverColor: v || '#ffffff' } ); }
350 },
351 {
352 label: __( 'Border', 'blockenberg' ),
353 value: a.borderColor,
354 onChange: function ( v ) { setAttributes( { borderColor: v || '#1e293b' } ); }
355 }
356 ]
357 } )
358 ),
359 el(
360 'div',
361 blockProps,
362 isFloating && el(
363 'p',
364 { className: 'bkbg-prb-editor-hint' },
365 __( 'Floating button — fixed on the front end', 'blockenberg' ) +
366 ' (' + ( a.position || 'bottom-right' ) + ')'
367 ),
368 el(
369 'button',
370 {
371 type: 'button',
372 className: 'bkbg-prb-btn',
373 style: buildBtnStyle( a ),
374 onClick: function ( e ) { e.preventDefault(); }
375 },
376 renderButtonChildren( a, false )
377 )
378 )
379 );
380 },
381
382 save: function ( props ) {
383 var a = props.attributes;
384 var isFloating = a.layout === 'floating';
385 var wrapStyle = Object.assign( {}, typoCssVars( a.typoBtn || {}, '--bkbg-prb-btn-' ) );
386
387 if ( isFloating ) {
388 Object.assign( wrapStyle, floatingPosStyle( a.position, a.offsetX, a.offsetY ) );
389 wrapStyle.position = 'fixed';
390 wrapStyle.zIndex = a.zIndex || 9990;
391 } else {
392 wrapStyle.textAlign = a.alignBtn || 'left';
393 }
394
395 var blockProps = useBlockProps.save( {
396 className: 'bkbg-prb-wrap' + ( isFloating ? ' bkbg-prb-wrap--floating' : ' bkbg-prb-wrap--inline' ),
397 style: wrapStyle
398 } );
399
400 var aria = a.ariaLabel || a.label || __( 'Print page', 'blockenberg' );
401
402 return el(
403 'div',
404 blockProps,
405 el(
406 'button',
407 {
408 type: 'button',
409 className: 'bkbg-prb-btn',
410 style: buildBtnStyle( a ),
411 'aria-label': aria,
412 'data-bkbg-print': '1'
413 },
414 renderButtonChildren( a, true )
415 )
416 );
417 }
418 } );
419 }() );
420