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 / morphing-text / index.js

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

188 lines 10.6 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 __ = 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