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 / cursor-spotlight / index.js

index.js in Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor 2.0.7, at blocks/cursor-spotlight/index.js

140 lines 10.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 ( function () {
2 var el = React.createElement;
3 var registerBlockType = wp.blocks.registerBlockType;
4 var useBlockProps = wp.blockEditor.useBlockProps;
5 var InspectorControls = wp.blockEditor.InspectorControls;
6 var MediaUpload = wp.blockEditor.MediaUpload;
7 var MediaUploadCheck = wp.blockEditor.MediaUploadCheck;
8 var PanelBody = wp.components.PanelBody;
9 var RangeControl = wp.components.RangeControl;
10 var SelectControl = wp.components.SelectControl;
11 var TextControl = wp.components.TextControl;
12 var TextareaControl = wp.components.TextareaControl;
13 var ToggleControl = wp.components.ToggleControl;
14 var Button = wp.components.Button;
15 var PanelColorSettings = wp.blockEditor.PanelColorSettings;
16
17 var _csTC, _csTV;
18 function _tc() { return _csTC || (_csTC = window.bkbgTypographyControl); }
19 function _tv(typo, prefix) { return _csTV ? _csTV(typo, prefix) : ((_csTV = window.bkbgTypoCssVars) ? _csTV(typo, prefix) : {}); }
20
21 var IDLE_MODES = [
22 { value: 'center', label: 'Center of section' },
23 { value: 'full', label: 'Reveal all (no dark)' },
24 { value: 'dark', label: 'Fully dark' }
25 ];
26
27 registerBlockType('blockenberg/cursor-spotlight', {
28 title: 'Cursor Spotlight',
29 icon: 'visibility',
30 category: 'bkbg-effects',
31
32 edit: function (props) {
33 var attr = props.attributes; var setAttr = props.setAttributes;
34
35 // Idle "center" spotlight position for editor preview
36 var spotR = attr.spotlightSize || 280;
37 var blur = attr.spotlightBlur || 40;
38 var mask = 'radial-gradient(circle ' + spotR + 'px at 50% 50%, ' +
39 (attr.spotColor || '#fff') + ' 0%, transparent ' + (spotR + blur) + 'px)';
40 var dimRgb = hexToRgbStr(attr.dimColor || '#000');
41 var dimOverlay = 'rgba(' + dimRgb + ',' + (attr.dimOpacity || 0.92) + ')';
42
43 return el(React.Fragment, null,
44 el(InspectorControls, null,
45 el(PanelBody, { title: 'Content', initialOpen: true },
46 el(SelectControl, { __nextHasNoMarginBottom: true, label: 'Heading Tag', value: attr.tag, options: ['h1','h2','h3','h4','h5','h6'].map(function(t){return{value:t,label:t.toUpperCase()};}), onChange: function(v){ setAttr({tag:v}); } }),
47 el(TextControl, { __nextHasNoMarginBottom: true, label: 'Heading', value: attr.heading, onChange: function(v){ setAttr({heading:v}); } }),
48 el(TextareaControl,{ __nextHasNoMarginBottom: true, label: 'Subtext', value: attr.subtext, onChange: function(v){ setAttr({subtext:v}); } }),
49 el(ToggleControl, { __nextHasNoMarginBottom: true, label: 'Show Hint Text', checked: attr.showHint, onChange: function(v){ setAttr({showHint:v}); } }),
50 attr.showHint && el(TextControl, { __nextHasNoMarginBottom: true, label: 'Hint', value: attr.hintText, onChange: function(v){ setAttr({hintText:v}); } })
51 ),
52 el(PanelBody, { title: 'Spotlight', initialOpen: true },
53 el(RangeControl, { __nextHasNoMarginBottom: true, label: 'Spotlight Size (px)', value: attr.spotlightSize, min: 60, max: 800, onChange: function(v){ setAttr({spotlightSize:v}); } }),
54 el(RangeControl, { __nextHasNoMarginBottom: true, label: 'Edge Blur (px)', value: attr.spotlightBlur, min: 0, max: 200, onChange: function(v){ setAttr({spotlightBlur:v}); } }),
55 el(RangeControl, { __nextHasNoMarginBottom: true, label: 'Dim Opacity', value: attr.dimOpacity, min: 0.1, max: 1, step: 0.05, onChange: function(v){ setAttr({dimOpacity:v}); } }),
56 el(SelectControl, { __nextHasNoMarginBottom: true, label: 'Idle Mode', value: attr.idleMode, options: IDLE_MODES, onChange: function(v){ setAttr({idleMode:v}); } }),
57 el(ToggleControl, { __nextHasNoMarginBottom: true, label: 'Smooth Follow', checked: attr.followSmooth, onChange: function(v){ setAttr({followSmooth:v}); } })
58 ),
59 el(PanelBody, { title: 'Section Size', initialOpen: false },
60 el(RangeControl, { __nextHasNoMarginBottom: true, label: 'Section Height (px)', value: attr.sectionHeight, min: 200, max: 1200, onChange: function(v){ setAttr({sectionHeight:v}); } }),
61 el(RangeControl, { __nextHasNoMarginBottom: true, label: 'Border Radius (px)', value: attr.borderRadius, min: 0, max: 48, onChange: function(v){ setAttr({borderRadius:v}); } })
62 ),
63 el(PanelBody, { title: 'Typography', initialOpen: false },
64 _tc() && el(_tc(), { label: 'Heading', typo: attr.typoHeading || {}, onChange: function(v) { setAttr({ typoHeading: v }); } }),
65 _tc() && el(_tc(), { label: 'Subtext', typo: attr.typoSubtext || {}, onChange: function(v) { setAttr({ typoSubtext: v }); } }),
66 el(SelectControl, { __nextHasNoMarginBottom: true, label: 'Text Align', value: attr.textAlign, options: [{value:'left',label:'Left'},{value:'center',label:'Center'},{value:'right',label:'Right'}], onChange: function(v){ setAttr({textAlign:v}); } })
67 ),
68 el(PanelBody, { title: 'Background Image', initialOpen: false },
69 el(MediaUploadCheck, null,
70 el(MediaUpload, {
71 onSelect: function(m){ setAttr({bgImage:m.url,bgImageId:m.id}); },
72 allowedTypes: ['image'],
73 value: attr.bgImageId,
74 render: function(r){ return el('div', null,
75 attr.bgImage ? el(Button, {variant:'secondary',isSmall:true,onClick:r.open},'Change BG Image') : el(Button,{variant:'primary',onClick:r.open},'Select BG Image'),
76 attr.bgImage && el(Button,{variant:'tertiary',isSmall:true,isDestructive:true,style:{marginLeft:8},onClick:function(){setAttr({bgImage:'',bgImageId:0});}},'Remove')
77 ); }
78 })
79 ),
80 attr.bgImage && el(RangeControl, { __nextHasNoMarginBottom: true, label: 'BG Image Opacity', value: attr.bgImageOpacity, min: 0, max: 1, step: 0.05, onChange: function(v){ setAttr({bgImageOpacity:v}); } })
81 ),
82 el(PanelColorSettings, {
83 title: 'Colors', initialOpen: false,
84 colorSettings: [
85 { value: attr.bgColor, onChange: function(v){ setAttr({bgColor: v||'#0c0a1e'}); }, label: 'Section Background' },
86 { value: attr.dimColor, onChange: function(v){ setAttr({dimColor: v||'#000000'}); }, label: 'Dim Color' },
87 { value: attr.spotColor, onChange: function(v){ setAttr({spotColor: v||'#ffffff'}); }, label: 'Spotlight Color' },
88 { value: attr.textColor, onChange: function(v){ setAttr({textColor: v||'#ffffff'}); }, label: 'Text Color' },
89 { value: attr.accentColor,onChange: function(v){ setAttr({accentColor:v||'#a78bfa'}); }, label: 'Accent Color' }
90 ]
91 })
92 ),
93
94 el('div', useBlockProps(),
95 el('div', {
96 className: 'bkbg-cs-editor-preview',
97 style: Object.assign({
98 position: 'relative',
99 height: (attr.sectionHeight || 500) + 'px',
100 borderRadius: (attr.borderRadius || 16) + 'px',
101 overflow: 'hidden',
102 backgroundColor: attr.bgColor || '#0c0a1e',
103 display: 'flex', alignItems: 'center', justifyContent: 'center'
104 },
105 { '--bkbg-cs-hdg-fs': (attr.fontSize || 48) + 'px', '--bkbg-cs-hdg-fw': attr.fontWeight || '800', '--bkbg-cs-sub-fs': (attr.subtextSize || 18) + 'px' },
106 _tv(attr.typoHeading, '--bkbg-cs-hdg-'),
107 _tv(attr.typoSubtext, '--bkbg-cs-sub-'))
108 },
109 // BG image
110 attr.bgImage && el('img', { src: attr.bgImage, style: { position:'absolute',inset:0,width:'100%',height:'100%',objectFit:'cover',opacity:attr.bgImageOpacity||0.5 } }),
111 // Dark overlay
112 el('div', { style: { position:'absolute',inset:0, background: dimOverlay, maskImage: mask, WebkitMaskImage: mask } }),
113 // Content
114 el('div', {
115 style: { position:'relative', zIndex:2, textAlign:attr.textAlign||'center', padding:'32px', color: attr.textColor||'#fff' }
116 },
117 el(attr.tag||'h2', { className: 'bkbg-cs-heading', style: { margin:0,color:attr.textColor||'#fff' } }, attr.heading),
118 attr.subtext && el('p', { className: 'bkbg-cs-subtext', style: { marginTop:16,opacity:0.75,color:attr.textColor||'#fff' } }, attr.subtext),
119 attr.showHint && el('p', { style: { marginTop:24,fontSize:13,color:attr.accentColor||'#a78bfa',opacity:0.8,letterSpacing:'0.1em',textTransform:'uppercase' } }, '' + (attr.hintText||'Move cursor to reveal') + '')
120 )
121 )
122 )
123 );
124 },
125
126 save: function (props) {
127 return el('div', useBlockProps.save(),
128 el('div', { className:'bkbg-cs-app', 'data-opts':JSON.stringify(props.attributes) })
129 );
130 }
131 });
132
133 function hexToRgbStr(hex) {
134 hex = hex.replace(/^#/, '');
135 if (hex.length === 3) hex = hex.split('').map(function(c){return c+c;}).join('');
136 var n = parseInt(hex, 16);
137 return [(n>>16)&255,(n>>8)&255,n&255].join(',');
138 }
139 }() );
140