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 / word-flip / index.js

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

155 lines 9.4 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
6 var _tc, _tvf;
7 Object.defineProperty(window, '_tc', { get: function () { return _tc || (_tc = window.bkbgTypographyControl); } });
8 Object.defineProperty(window, '_tvf', { get: function () { return _tvf || (_tvf = window.bkbgTypoCssVars); } });
9 function getTypoControl(label, key, attrs, setA) { return _tc(label, key, attrs, setA); }
10 function getTypoCssVars(attrs) {
11 var v = {};
12 _tvf(v, 'headingTypo', attrs, '--bkwf-hd-');
13 return v;
14 }
15 var InspectorControls = wp.blockEditor.InspectorControls;
16 var PanelBody = wp.components.PanelBody;
17 var RangeControl = wp.components.RangeControl;
18 var SelectControl = wp.components.SelectControl;
19 var TextControl = wp.components.TextControl;
20 var Button = wp.components.Button;
21 var PanelColorSettings = wp.blockEditor.PanelColorSettings;
22 var ToggleControl = wp.components.ToggleControl;
23
24 var FLIP_MODES = [
25 { value: 'roll', label: 'Roll — slides up continuously' },
26 { value: 'flip-3d', label: 'Flip 3D — rotateX perspective' },
27 { value: 'fade-up', label: 'Fade + Slide Up' },
28 { value: 'zoom', label: 'Zoom In' }
29 ];
30
31 var UNDERLINES = [
32 { value: 'none', label: 'None' },
33 { value: 'solid', label: 'Solid Line' },
34 { value: 'wavy', label: 'Wavy' },
35 { value: 'dashed', label: 'Dashed' },
36 { value: 'highlight', label: 'Highlight Block' }
37 ];
38
39 var TAGS = ['h1','h2','h3','h4','h5','h6','p'].map(function(t){ return { value: t, label: t.toUpperCase() }; });
40
41 function WordFlipPreview(props) {
42 var attr = props.attr;
43 var words = (attr.words && attr.words.length) ? attr.words : ['designers'];
44 var _s = React.useState(0);
45 var idx = _s[0]; var setIdx = _s[1];
46
47 React.useEffect(function () {
48 var t = setInterval(function () { setIdx(function(i){ return (i+1)%words.length; }); }, attr.interval || 2200);
49 return function(){ clearInterval(t); };
50 }, [words.length, attr.interval]);
51
52 var flipStyle = {
53 display: 'inline-block',
54 color: attr.flipColor || '#7c3aed',
55 backgroundColor: attr.flipBg || 'transparent',
56 borderRadius: (attr.flipBorderRadius || 4) + 'px',
57 padding: '0 ' + (attr.flipPaddingH || 8) + 'px',
58 marginLeft: '0.25em',
59 transition: 'all 0.35s ease',
60 textDecoration: attr.underlineStyle !== 'none' && attr.underlineStyle !== 'highlight' ? 'underline' : 'none',
61 textDecorationStyle: attr.underlineStyle !== 'none' && attr.underlineStyle !== 'highlight' ? attr.underlineStyle : undefined,
62 textDecorationColor: attr.underlineColor || '#7c3aed'
63 };
64
65 return el('div', {
66 style: {
67 padding: (attr.paddingV||32)+'px '+(attr.paddingH||24)+'px',
68 backgroundColor: attr.showBg ? (attr.bgColor||'#fff') : 'transparent',
69 borderRadius: (attr.borderRadius||0)+'px',
70 textAlign: attr.textAlign||'center'
71 }
72 },
73 el(attr.tag||'h2', {
74 className: 'bkbg-wf-heading',
75 style: { margin:0, padding:0, color:attr.staticColor||'#0f172a' }
76 },
77 attr.staticBefore && el('span', null, attr.staticBefore),
78 el('span', { style: flipStyle }, words[idx]),
79 attr.staticAfter && el('span', null, ' '+attr.staticAfter)
80 )
81 );
82 }
83
84 registerBlockType('blockenberg/word-flip', {
85 title: 'Word Flip',
86 icon: 'sort',
87 category: 'bkbg-effects',
88
89 edit: function (props) {
90 var attr = props.attributes; var setAttr = props.setAttributes;
91
92 function updateWord(i, val){ var w=attr.words.slice(); w[i]=val; setAttr({words:w}); }
93 function addWord(){ setAttr({words:attr.words.concat(['new'])}); }
94 function removeWord(i){ var w=attr.words.slice(); w.splice(i,1); setAttr({words:w}); }
95
96 return el(React.Fragment, null,
97 el(InspectorControls, null,
98 el(PanelBody, { title:'Words List', initialOpen:true },
99 el('p',{style:{fontSize:12,color:'#6b7280',margin:'0 0 8px'}},'Words that flip into the heading:'),
100 attr.words.map(function(w,i) {
101 return el('div',{key:i,style:{display:'flex',gap:6,marginBottom:6}},
102 el(TextControl,{__nextHasNoMarginBottom:true,value:w,onChange:function(v){updateWord(i,v);}}),
103 el(Button,{variant:'tertiary',isSmall:true,isDestructive:true,onClick:function(){removeWord(i);},disabled:attr.words.length<=1},'')
104 );
105 }),
106 el(Button,{variant:'secondary',isSmall:true,onClick:addWord,style:{marginTop:4}},'+ Add Word')
107 ),
108 el(PanelBody, { title:'Static Text', initialOpen:false },
109 el(TextControl,{__nextHasNoMarginBottom:true,label:'Before',value:attr.staticBefore,onChange:function(v){setAttr({staticBefore:v});}}),
110 el(TextControl,{__nextHasNoMarginBottom:true,label:'After',value:attr.staticAfter,onChange:function(v){setAttr({staticAfter:v});}})
111 ),
112 el(PanelBody, { title:'Animation', initialOpen:true },
113 el(SelectControl,{__nextHasNoMarginBottom:true,label:'Flip Mode',value:attr.flipMode,options:FLIP_MODES,onChange:function(v){setAttr({flipMode:v});}}),
114 el(RangeControl,{__nextHasNoMarginBottom:true,label:'Interval (ms)',value:attr.interval,min:500,max:8000,step:100,onChange:function(v){setAttr({interval:v});}}),
115 el(RangeControl,{__nextHasNoMarginBottom:true,label:'Flip Speed (ms)',value:attr.flipSpeed,min:100,max:1200,step:20,onChange:function(v){setAttr({flipSpeed:v});}})
116 ),
117 el(PanelBody, { title:'Typography', initialOpen:false },
118 getTypoControl('Heading', 'headingTypo', attr, setAttr),
119 el(SelectControl,{__nextHasNoMarginBottom:true,label:'HTML Tag',value:attr.tag,options:TAGS,onChange:function(v){setAttr({tag:v});}}),
120 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});}})
121 ),
122 el(PanelBody, { title:'Flip Word Style', initialOpen:false },
123 el(SelectControl,{__nextHasNoMarginBottom:true,label:'Underline / Decoration',value:attr.underlineStyle,options:UNDERLINES,onChange:function(v){setAttr({underlineStyle:v});}}),
124 el(RangeControl,{__nextHasNoMarginBottom:true,label:'Padding Horizontal (px)',value:attr.flipPaddingH,min:0,max:40,onChange:function(v){setAttr({flipPaddingH:v});}}),
125 el(RangeControl,{__nextHasNoMarginBottom:true,label:'Border Radius (px)',value:attr.flipBorderRadius,min:0,max:40,onChange:function(v){setAttr({flipBorderRadius:v});}})
126 ),
127 el(PanelBody, { title:'Background', initialOpen:false },
128 el(ToggleControl,{__nextHasNoMarginBottom:true,label:'Show Background',checked:attr.showBg,onChange:function(v){setAttr({showBg:v});}}),
129 el(RangeControl,{__nextHasNoMarginBottom:true,label:'Padding V (px)',value:attr.paddingV,min:0,max:120,onChange:function(v){setAttr({paddingV:v});}}),
130 el(RangeControl,{__nextHasNoMarginBottom:true,label:'Padding H (px)',value:attr.paddingH,min:0,max:120,onChange:function(v){setAttr({paddingH:v});}}),
131 el(RangeControl,{__nextHasNoMarginBottom:true,label:'Block Radius (px)',value:attr.borderRadius,min:0,max:60,onChange:function(v){setAttr({borderRadius:v});}})
132 ),
133 el(PanelColorSettings, {
134 title:'Colors', initialOpen: false,
135 colorSettings:[
136 {value:attr.staticColor,onChange:function(v){setAttr({staticColor:v||'#0f172a'});},label:'Static Text'},
137 {value:attr.flipColor, onChange:function(v){setAttr({flipColor: v||'#7c3aed'});},label:'Flip Word Color'},
138 {value:attr.flipBg, onChange:function(v){setAttr({flipBg: v||'' });},label:'Flip Word Background'},
139 {value:attr.underlineColor,onChange:function(v){setAttr({underlineColor:v||'#7c3aed'});},label:'Decoration Color'},
140 attr.showBg && {value:attr.bgColor,onChange:function(v){setAttr({bgColor:v||'#fff'});},label:'Block Background'}
141 ].filter(Boolean)
142 })
143 ),
144 el('div', useBlockProps({ style: getTypoCssVars(attr) }), el(WordFlipPreview, {attr:attr}))
145 );
146 },
147
148 save: function (props) {
149 return el('div', useBlockProps.save({ style: getTypoCssVars(props.attributes) }),
150 el('div', { className:'bkbg-wf-app', 'data-opts':JSON.stringify(props.attributes) })
151 );
152 }
153 });
154 }() );
155