| 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 |
|