| 1 |
( function () { |
| 2 |
var el = React.createElement; |
| 3 |
var __ = wp.i18n.__; |
| 4 |
var registerBlockType = wp.blocks.registerBlockType; |
| 5 |
var useBlockProps = wp.blockEditor.useBlockProps; |
| 6 |
var InspectorControls = wp.blockEditor.InspectorControls; |
| 7 |
var PanelBody = wp.components.PanelBody; |
| 8 |
var ToggleControl = wp.components.ToggleControl; |
| 9 |
var RangeControl = wp.components.RangeControl; |
| 10 |
var SelectControl = wp.components.SelectControl; |
| 11 |
var TextControl = wp.components.TextControl; |
| 12 |
var Button = wp.components.Button; |
| 13 |
var PanelColorSettings = wp.blockEditor.PanelColorSettings; |
| 14 |
|
| 15 |
var _tc, _tv; |
| 16 |
function getTypoControl() { return _tc || (_tc = window.bkbgTypographyControl); } |
| 17 |
function getTypoCssVars() { return _tv || (_tv = window.bkbgTypoCssVars); } |
| 18 |
|
| 19 |
var MORPH_MODES = [ |
| 20 |
{ value: 'blur', label: 'Blur — letters blur in/out' }, |
| 21 |
{ value: 'crossfade', label: 'Crossfade — smooth opacity' }, |
| 22 |
{ value: 'slide-up', label: 'Slide Up' }, |
| 23 |
{ value: 'slide-down',label: 'Slide Down' }, |
| 24 |
{ value: 'typewriter',label: 'Typewriter — char by char' } |
| 25 |
]; |
| 26 |
|
| 27 |
var TAGS = ['h1','h2','h3','h4','h5','h6','p','div'].map(function(t){ return { value: t, label: t.toUpperCase() }; }); |
| 28 |
|
| 29 |
function MorphPreview(props) { |
| 30 |
var attr = props.attr; |
| 31 |
var words = attr.words && attr.words.length ? attr.words : ['build websites']; |
| 32 |
var _state = React.useState(0); |
| 33 |
var idx = _state[0]; var setIdx = _state[1]; |
| 34 |
|
| 35 |
React.useEffect(function () { |
| 36 |
var t = setInterval(function () { |
| 37 |
setIdx(function (i) { return (i + 1) % words.length; }); |
| 38 |
}, (attr.duration || 2500)); |
| 39 |
return function () { clearInterval(t); }; |
| 40 |
}, [words.length, attr.duration]); |
| 41 |
|
| 42 |
var grad = attr.useGradient |
| 43 |
? 'linear-gradient(90deg,' + (attr.morphColor || '#7c3aed') + ',' + (attr.morphColor2 || '#ec4899') + ')' |
| 44 |
: null; |
| 45 |
|
| 46 |
var morphStyle = { |
| 47 |
display: 'inline', |
| 48 |
color: !attr.useGradient ? (attr.morphColor || '#7c3aed') : 'transparent', |
| 49 |
background: grad || 'none', |
| 50 |
backgroundClip: grad ? 'text' : undefined, |
| 51 |
WebkitBackgroundClip: grad ? 'text' : undefined, |
| 52 |
WebkitTextFillColor: grad ? 'transparent' : undefined, |
| 53 |
transition: 'all 0.4s ease', |
| 54 |
marginLeft: '0.3em' |
| 55 |
}; |
| 56 |
|
| 57 |
return el('div', { |
| 58 |
className: 'bkbg-mt-wrap', |
| 59 |
style: { |
| 60 |
padding: (attr.paddingV || 32) + 'px ' + (attr.paddingH || 24) + 'px', |
| 61 |
backgroundColor: attr.showBg ? (attr.bgColor || '#fff') : 'transparent', |
| 62 |
borderRadius: (attr.borderRadius || 0) + 'px', |
| 63 |
textAlign: attr.textAlign || 'center' |
| 64 |
} |
| 65 |
}, |
| 66 |
el(attr.tag || 'h2', { |
| 67 |
className: 'bkbg-mt-heading', |
| 68 |
style: { |
| 69 |
margin: 0, padding: 0, |
| 70 |
color: attr.staticColor || '#1e293b' |
| 71 |
} |
| 72 |
}, |
| 73 |
attr.staticBefore && el('span', null, attr.staticBefore), |
| 74 |
el('span', { style: morphStyle }, words[idx]), |
| 75 |
attr.staticAfter && el('span', null, ' ' + attr.staticAfter), |
| 76 |
attr.cursor && el('span', { style: { borderRight: '3px solid currentColor', marginLeft: '2px', animation: 'bkbg-mt-blink 1s step-end infinite' } }) |
| 77 |
) |
| 78 |
); |
| 79 |
} |
| 80 |
|
| 81 |
registerBlockType('blockenberg/morphing-text', { |
| 82 |
title: 'Morphing Text', |
| 83 |
icon: 'editor-textcolor', |
| 84 |
category: 'bkbg-effects', |
| 85 |
|
| 86 |
edit: function (props) { |
| 87 |
var attr = props.attributes; |
| 88 |
var setAttr = props.setAttributes; |
| 89 |
|
| 90 |
function updateWord(i, val) { |
| 91 |
var words = attr.words.slice(); |
| 92 |
words[i] = val; |
| 93 |
setAttr({ words: words }); |
| 94 |
} |
| 95 |
function addWord() { setAttr({ words: attr.words.concat(['new word']) }); } |
| 96 |
function removeWord(i) { |
| 97 |
var words = attr.words.slice(); |
| 98 |
words.splice(i, 1); |
| 99 |
setAttr({ words: words }); |
| 100 |
} |
| 101 |
|
| 102 |
return el(React.Fragment, null, |
| 103 |
el(InspectorControls, null, |
| 104 |
el(PanelBody, { title: 'Words', initialOpen: true }, |
| 105 |
el('p', { style: { fontSize: 12, color: '#6b7280', margin: '0 0 8px' } }, 'The morphing text cycles through these words:'), |
| 106 |
attr.words.map(function (w, i) { |
| 107 |
return el('div', { key: i, style: { display: 'flex', gap: 6, marginBottom: 6 } }, |
| 108 |
el(TextControl, { __nextHasNoMarginBottom: true, value: w, onChange: function (v) { updateWord(i, v); } }), |
| 109 |
el(Button, { variant: 'tertiary', isSmall: true, isDestructive: true, onClick: function () { removeWord(i); }, disabled: attr.words.length <= 1 }, '✕') |
| 110 |
); |
| 111 |
}), |
| 112 |
el(Button, { variant: 'secondary', isSmall: true, onClick: addWord, style: { marginTop: 4 } }, '+ Add Word') |
| 113 |
), |
| 114 |
el(PanelBody, { title: 'Static Text', initialOpen: false }, |
| 115 |
el(TextControl, { __nextHasNoMarginBottom: true, label: 'Text Before', value: attr.staticBefore, onChange: function (v) { setAttr({ staticBefore: v }); } }), |
| 116 |
el(TextControl, { __nextHasNoMarginBottom: true, label: 'Text After', value: attr.staticAfter, onChange: function (v) { setAttr({ staticAfter: v }); } }) |
| 117 |
), |
| 118 |
el(PanelBody, { title: 'Animation', initialOpen: true }, |
| 119 |
el(SelectControl, { __nextHasNoMarginBottom: true, label: 'Morph Mode', value: attr.morphMode, options: MORPH_MODES, onChange: function (v) { setAttr({ morphMode: v }); } }), |
| 120 |
el(RangeControl, { __nextHasNoMarginBottom: true, label: 'Word Duration (ms)', value: attr.duration, min: 500, max: 8000, step: 100, onChange: function (v) { setAttr({ duration: v }); } }), |
| 121 |
el(RangeControl, { __nextHasNoMarginBottom: true, label: 'Pause Between (ms)', value: attr.pauseDuration, min: 0, max: 5000, step: 100, onChange: function (v) { setAttr({ pauseDuration: v }); } }), |
| 122 |
el(ToggleControl, { __nextHasNoMarginBottom: true, label: 'Loop', checked: attr.loop, onChange: function (v) { setAttr({ loop: v }); } }), |
| 123 |
el(ToggleControl, { __nextHasNoMarginBottom: true, label: 'Blinking Cursor', checked: attr.cursor, onChange: function (v) { setAttr({ cursor: v }); } }) |
| 124 |
), |
| 125 |
el(PanelBody, { title: 'Typography', initialOpen: false }, |
| 126 |
el(SelectControl, { __nextHasNoMarginBottom: true, label: 'HTML Tag', value: attr.tag, options: TAGS, onChange: function (v) { setAttr({ tag: v }); } }), |
| 127 |
el(getTypoControl(), { |
| 128 |
label: __('Heading', 'blockenberg'), |
| 129 |
value: attr.headingTypo, |
| 130 |
onChange: function (v) { setAttr({ headingTypo: v }); } |
| 131 |
}), |
| 132 |
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 }); } }) |
| 133 |
), |
| 134 |
el(PanelBody, { title: 'Background', initialOpen: false }, |
| 135 |
el(ToggleControl, { __nextHasNoMarginBottom: true, label: 'Show Background', checked: attr.showBg, onChange: function (v) { setAttr({ showBg: v }); } }), |
| 136 |
el(RangeControl, { __nextHasNoMarginBottom: true, label: 'Padding Vertical (px)', value: attr.paddingV, min: 0, max: 120, onChange: function (v) { setAttr({ paddingV: v }); } }), |
| 137 |
el(RangeControl, { __nextHasNoMarginBottom: true, label: 'Padding Horizontal (px)', value: attr.paddingH, min: 0, max: 120, onChange: function (v) { setAttr({ paddingH: v }); } }), |
| 138 |
el(RangeControl, { __nextHasNoMarginBottom: true, label: 'Border Radius (px)', value: attr.borderRadius, min: 0, max: 60, onChange: function (v) { setAttr({ borderRadius: v }); } }) |
| 139 |
), |
| 140 |
el(PanelColorSettings, { |
| 141 |
title: 'Colors', |
| 142 |
initialOpen: false, |
| 143 |
colorSettings: [ |
| 144 |
{ value: attr.staticColor, onChange: function (v) { setAttr({ staticColor: v || '#1e293b' }); }, label: 'Static Text Color' }, |
| 145 |
{ value: attr.morphColor, onChange: function (v) { setAttr({ morphColor: v || '#7c3aed' }); }, label: 'Morph Color 1' }, |
| 146 |
{ value: attr.morphColor2, onChange: function (v) { setAttr({ morphColor2: v || '#ec4899' }); }, label: 'Morph Color 2 (gradient)' }, |
| 147 |
attr.showBg && { value: attr.bgColor, onChange: function (v) { setAttr({ bgColor: v || '#fff' }); }, label: 'Background' } |
| 148 |
].filter(Boolean) |
| 149 |
}), |
| 150 |
el(PanelBody, { title: 'Morph Color Style', initialOpen: false }, |
| 151 |
el(ToggleControl, { __nextHasNoMarginBottom: true, label: 'Use Gradient on Morphing Word', checked: attr.useGradient, onChange: function (v) { setAttr({ useGradient: v }); } }) |
| 152 |
) |
| 153 |
), |
| 154 |
|
| 155 |
el('div', useBlockProps((function () { |
| 156 |
var _tvf = getTypoCssVars(); |
| 157 |
var s = {}; |
| 158 |
Object.assign(s, _tvf(attr.headingTypo, '--bkbg-mrt-hd-')); |
| 159 |
return { style: s }; |
| 160 |
})()), |
| 161 |
el(MorphPreview, { attr: attr }) |
| 162 |
) |
| 163 |
); |
| 164 |
}, |
| 165 |
|
| 166 |
deprecated: [{ |
| 167 |
save: function (props) { |
| 168 |
return el('div', useBlockProps.save(), |
| 169 |
el('div', { className: 'bkbg-mt-app', 'data-opts': JSON.stringify(props.attributes) }) |
| 170 |
); |
| 171 |
} |
| 172 |
}], |
| 173 |
|
| 174 |
save: function (props) { |
| 175 |
var a = props.attributes; |
| 176 |
var blockProps = useBlockProps.save((function () { |
| 177 |
var _tvf = getTypoCssVars(); |
| 178 |
var s = {}; |
| 179 |
Object.assign(s, _tvf(a.headingTypo, '--bkbg-mrt-hd-')); |
| 180 |
return { style: s }; |
| 181 |
})()); |
| 182 |
return el('div', blockProps, |
| 183 |
el('div', { className: 'bkbg-mt-app', 'data-opts': JSON.stringify(a) }) |
| 184 |
); |
| 185 |
} |
| 186 |
}); |
| 187 |
}() ); |
| 188 |
|