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 / gradient-border-card / index.js

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

128 lines 10.5 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 PanelBody = wp.components.PanelBody;
7 var RangeControl = wp.components.RangeControl;
8 var SelectControl = wp.components.SelectControl;
9 var TextControl = wp.components.TextControl;
10 var TextareaControl = wp.components.TextareaControl;
11 var ToggleControl = wp.components.ToggleControl;
12 var Button = wp.components.Button;
13 var PanelColorSettings = wp.blockEditor.PanelColorSettings;
14
15 /* ── Typography lazy getters ── */
16 function _tc() { return window.bkbgTypographyControl || null; }
17 function _tv() { return window.bkbgTypoCssVars || function () { return {}; }; }
18 var IP = function () { return window.bkbgIconPicker; };
19
20 var ANIM_TYPES = [
21 { value: 'rotate', label: 'Rotate — border spins' },
22 { value: 'shift', label: 'Shift — gradient slides' },
23 { value: 'pulse', label: 'Pulse — opacity breathes' },
24 { value: 'static', label: 'Static — no animation' }
25 ];
26
27 function CardPreview(props) {
28 var a = props.attr;
29 var colors = a.borderColors || ['#7c3aed','#ec4899','#06b6d4','#f59e0b'];
30 var gradient = 'conic-gradient(' + colors.join(', ') + ', ' + colors[0] + ')';
31
32 var wrapS = Object.assign({ maxWidth: (a.maxWidth || 420) + 'px', margin: '0 auto', position: 'relative', padding: (a.borderWidth || 2) + 'px', borderRadius: (a.borderRadius || 20) + 'px', background: gradient }, _tv()(a.typoTitle,'--bkbg-gbc-tt-'), _tv()(a.typoBody,'--bkbg-gbc-bd-'), _tv()(a.typoBadge,'--bkbg-gbc-bg-'));
33
34 return el('div', { style: wrapS },
35 el('div', {
36 style: { background: a.cardBg || '#0f172a', borderRadius: Math.max(0, (a.borderRadius||20) - (a.borderWidth||2)) + 'px', padding: (a.paddingV||32)+'px '+(a.paddingH||28)+'px', textAlign: a.textAlign||'left', color: a.textColor||'#e2e8f0', position: 'relative', zIndex: 1 }
37 },
38 a.showBadge && a.badge && el('div', { className:'bkbg-gbc-badge', style: { background:a.badgeBg||'#7c3aed', color:a.badgeColor||'#fff', borderRadius:'50px', padding:'2px 12px', marginBottom:12 } }, a.badge),
39 a.showIcon && el('div', { className: 'bkbg-gbc-icon', style: { fontSize:(a.iconSize||36)+'px', color:a.iconColor||'#a78bfa', marginBottom:12 } },
40 (!a.iconType || a.iconType === 'custom-char') ? (a.icon || '') : IP().buildEditorIcon(a.iconType, a.icon, a.iconDashicon, a.iconImageUrl, a.iconDashiconColor)
41 ),
42 el(a.titleTag||'h3', { className:'bkbg-gbc-title', style: { margin:'0 0 10px', color:a.titleColor||'#fff' } }, a.title),
43 el('p', { className:'bkbg-gbc-desc', style: { margin:0, color:a.textColor||'#e2e8f0' } }, a.description)
44 )
45 );
46 }
47
48 registerBlockType('blockenberg/gradient-border-card', {
49 title: 'Gradient Border Card',
50 icon: 'tagcloud',
51 category: 'bkbg-effects',
52
53 edit: function (props) {
54 var attr = props.attributes; var setAttr = props.setAttributes;
55
56 function updateColor(i, val) { var c = (attr.borderColors||[]).slice(); c[i] = val; setAttr({borderColors:c}); }
57 function addColor() { setAttr({borderColors:(attr.borderColors||['#7c3aed']).concat(['#ffffff'])}); }
58 function removeColor(i) { var c = (attr.borderColors||[]).slice(); c.splice(i,1); setAttr({borderColors:c}); }
59
60 return el(React.Fragment, null,
61 el(InspectorControls, null,
62 el(PanelBody, { title:'Content', initialOpen:true },
63 el(ToggleControl,{__nextHasNoMarginBottom:true,label:'Show Badge',checked:attr.showBadge,onChange:function(v){setAttr({showBadge:v});}}),
64 attr.showBadge && el(TextControl,{__nextHasNoMarginBottom:true,label:'Badge Text',value:attr.badge,onChange:function(v){setAttr({badge:v});}}),
65 el(ToggleControl,{__nextHasNoMarginBottom:true,label:'Show Icon',checked:attr.showIcon,onChange:function(v){setAttr({showIcon:v});}}),
66 attr.showIcon && el('p', { style: { fontSize: '11px', fontWeight: 600, marginTop: '8px' } }, 'Icon'),
67 attr.showIcon && el(IP().IconPickerControl, IP().iconPickerProps(attr, setAttr)),
68 el(SelectControl,{__nextHasNoMarginBottom:true,label:'Title Tag',value:attr.titleTag,options:['h2','h3','h4','h5'].map(function(t){return{value:t,label:t.toUpperCase()};}),onChange:function(v){setAttr({titleTag:v});}}),
69 el(TextControl,{__nextHasNoMarginBottom:true,label:'Title',value:attr.title,onChange:function(v){setAttr({title:v});}}),
70 el(TextareaControl,{__nextHasNoMarginBottom:true,label:'Description',value:attr.description,onChange:function(v){setAttr({description:v});}})
71 ),
72 el(PanelBody, { title:'Border Gradient', initialOpen:true },
73 el(SelectControl,{__nextHasNoMarginBottom:true,label:'Animation Type',value:attr.animType,options:ANIM_TYPES,onChange:function(v){setAttr({animType:v});}}),
74 attr.animType !== 'static' && el(RangeControl,{__nextHasNoMarginBottom:true,label:'Animation Speed (s)',value:attr.animSpeed,min:0.5,max:20,step:0.5,onChange:function(v){setAttr({animSpeed:v});}}),
75 el(RangeControl,{__nextHasNoMarginBottom:true,label:'Border Width (px)',value:attr.borderWidth,min:1,max:12,onChange:function(v){setAttr({borderWidth:v});}}),
76 el(RangeControl,{__nextHasNoMarginBottom:true,label:'Glow Blur (px)',value:attr.glowBlur,min:0,max:60,onChange:function(v){setAttr({glowBlur:v});}}),
77 el(RangeControl,{__nextHasNoMarginBottom:true,label:'Glow Opacity',value:attr.glowOpacity,min:0,max:1,step:0.05,onChange:function(v){setAttr({glowOpacity:v});}}),
78 el('div', { style:{marginTop:8} },
79 el('strong',{style:{display:'block',fontSize:12,marginBottom:6}},'Border Colors'),
80 (attr.borderColors||[]).map(function(c,i){
81 return el('div',{key:i,style:{display:'flex',gap:8,marginBottom:4,alignItems:'center'}},
82 el('input',{type:'color',value:c,style:{width:32,height:28,cursor:'pointer',border:'1px solid #ccc',borderRadius:4},onChange:function(e){updateColor(i,e.target.value);}}),
83 el('span',{style:{flex:1,fontFamily:'monospace',fontSize:12}},c),
84 el(Button,{variant:'tertiary',isSmall:true,isDestructive:true,onClick:function(){removeColor(i);},disabled:(attr.borderColors||[]).length<=2},'')
85 );
86 }),
87 el(Button,{variant:'secondary',isSmall:true,style:{marginTop:4},onClick:addColor},'+ Add Color')
88 ),
89 el(ToggleControl,{__nextHasNoMarginBottom:true,label:'Pause on Hover',checked:attr.pauseOnHover,onChange:function(v){setAttr({pauseOnHover:v});}})
90 ),
91 el(PanelBody, { title:'Card Style', initialOpen:false },
92 el(RangeControl,{__nextHasNoMarginBottom:true,label:'Border Radius (px)',value:attr.borderRadius,min:0,max:60,onChange:function(v){setAttr({borderRadius:v});}}),
93 el(RangeControl,{__nextHasNoMarginBottom:true,label:'Padding Vertical (px)',value:attr.paddingV,min:8,max:80,onChange:function(v){setAttr({paddingV:v});}}),
94 el(RangeControl,{__nextHasNoMarginBottom:true,label:'Padding Horizontal (px)',value:attr.paddingH,min:8,max:80,onChange:function(v){setAttr({paddingH:v});}}),
95 el(RangeControl,{__nextHasNoMarginBottom:true,label:'Max Width (px)',value:attr.maxWidth,min:200,max:1200,onChange:function(v){setAttr({maxWidth:v});}}),
96 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});}}),
97 el(ToggleControl,{__nextHasNoMarginBottom:true,label:'Scale on Hover',checked:attr.hoverScale,onChange:function(v){setAttr({hoverScale:v});}})
98 ),
99 el(PanelBody, { title:'Typography', initialOpen:false },
100 _tc() && el(_tc(), { label:'Title', value:attr.typoTitle, onChange:function(v){ setAttr({typoTitle:v}); } }),
101 _tc() && el(_tc(), { label:'Body', value:attr.typoBody, onChange:function(v){ setAttr({typoBody:v}); } }),
102 _tc() && el(_tc(), { label:'Badge', value:attr.typoBadge, onChange:function(v){ setAttr({typoBadge:v}); } }),
103 attr.showIcon && el(RangeControl,{__nextHasNoMarginBottom:true,label:'Icon Size (px)',value:attr.iconSize,min:16,max:100,onChange:function(v){setAttr({iconSize:v});}})
104 ),
105 el(PanelColorSettings, {
106 title:'Colors',initialOpen:false,
107 colorSettings:[
108 {value:attr.cardBg, onChange:function(v){setAttr({cardBg: v||'#0f172a'});},label:'Card Background'},
109 {value:attr.titleColor,onChange:function(v){setAttr({titleColor:v||'#ffffff'});},label:'Title Color'},
110 {value:attr.textColor, onChange:function(v){setAttr({textColor: v||'#e2e8f0'});},label:'Body Text'},
111 {value:attr.iconColor, onChange:function(v){setAttr({iconColor: v||'#a78bfa'});},label:'Icon Color'},
112 attr.showBadge && {value:attr.badgeBg, onChange:function(v){setAttr({badgeBg: v||'#7c3aed'});},label:'Badge Background'},
113 attr.showBadge && {value:attr.badgeColor,onChange:function(v){setAttr({badgeColor:v||'#ffffff'});},label:'Badge Text'}
114 ].filter(Boolean)
115 })
116 ),
117 el('div', useBlockProps(), el(CardPreview, {attr:attr}))
118 );
119 },
120
121 save: function (props) {
122 return el('div', useBlockProps.save(),
123 el('div', { className:'bkbg-gbc-app', 'data-opts':JSON.stringify(props.attributes) })
124 );
125 }
126 });
127 }() );
128