PluginProbe
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor / 2.0.13
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor v2.0.13
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 / toggle / index.js

index.js in Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor 2.0.13, at blocks/toggle/index.js

303 lines 15.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 ( function () {
2 var el = wp.element.createElement;
3 var Fragment = wp.element.Fragment;
4 var __ = wp.i18n.__;
5 var useState = wp.element.useState;
6 var registerBlockType = wp.blocks.registerBlockType;
7 var InspectorControls = wp.blockEditor.InspectorControls;
8 var useBlockProps = wp.blockEditor.useBlockProps;
9 var RichText = wp.blockEditor.RichText;
10 var PanelBody = wp.components.PanelBody;
11 var PanelColorSettings = wp.blockEditor.PanelColorSettings;
12 var ToggleControl = wp.components.ToggleControl;
13 var RangeControl = wp.components.RangeControl;
14 var SelectControl = wp.components.SelectControl;
15 var TextControl = wp.components.TextControl;
16
17 // Resolve the shared components lazily without defining globals for each block.
18 function _tc(props, key, label) {
19 var Control = window.bkbgTypographyControl;
20 return Control ? el(Control, {
21 label: label,
22 value: props.attributes[key] || {},
23 onChange: function (value) { var update = {}; update[key] = value; props.setAttributes(update); }
24 }) : null;
25 }
26 function _tvf(typo, prefix) {
27 var cssVars = window.bkbgTypoCssVars;
28 return cssVars ? cssVars(typo || {}, prefix) : {};
29 }
30 function getTypoControl(props, attrName, label) { return _tc(props, attrName, label); }
31
32 var icons = {
33 chevron: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"/></svg>',
34 plus: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>',
35 arrow: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="5" x2="12" y2="19"/><polyline points="19 12 12 19 5 12"/></svg>'
36 };
37
38 function getIconEl(type) {
39 if (type === 'none') return null;
40 return el('span', {
41 className: 'bkbg-tgl-icon',
42 'aria-hidden': 'true',
43 dangerouslySetInnerHTML: { __html: icons[type] || icons.chevron }
44 });
45 }
46
47 var iconTypeOptions = [
48 { label: __('Chevron', 'blockenberg'), value: 'chevron' },
49 { label: __('Plus / Minus', 'blockenberg'), value: 'plus' },
50 { label: __('Arrow', 'blockenberg'), value: 'arrow' },
51 { label: __('None', 'blockenberg'), value: 'none' }
52 ];
53
54 var iconPositionOptions = [
55 { label: __('Right', 'blockenberg'), value: 'right' },
56 { label: __('Left', 'blockenberg'), value: 'left' }
57 ];
58
59 var layoutOptions = [
60 { label: __('Default', 'blockenberg'), value: 'default' },
61 { label: __('Boxed', 'blockenberg'), value: 'boxed' },
62 { label: __('Minimal', 'blockenberg'), value: 'minimal' },
63 { label: __('Bordered Left', 'blockenberg'), value: 'bordered' }
64 ];
65
66 var titleTagOptions = [
67 { label: 'H3', value: 'h3' },
68 { label: 'H4', value: 'h4' },
69 { label: 'H5', value: 'h5' },
70 { label: 'H6', value: 'h6' },
71 { label: 'p', value: 'p' },
72 { label: 'div', value: 'div' }
73 ];
74
75 registerBlockType('blockenberg/toggle', {
76 edit: function (props) {
77 var a = props.attributes;
78 var setAttributes = props.setAttributes;
79 var isOpen = useState(a.defaultOpen)[0];
80
81 var wrapStyle = {
82 '--bkbg-tgl-radius': a.borderRadius + 'px',
83 '--bkbg-tgl-padding': a.padding + 'px',
84 '--bkbg-tgl-speed': a.animationSpeed + 'ms',
85 '--bkbg-tgl-title-color': a.titleColor,
86 '--bkbg-tgl-title-bg': a.titleBg,
87 '--bkbg-tgl-title-hover-bg': a.titleHoverBg,
88 '--bkbg-tgl-active-title-bg': a.activeTitleBg,
89 '--bkbg-tgl-active-title-color': a.activeTitleColor,
90 '--bkbg-tgl-content-color': a.contentColor,
91 '--bkbg-tgl-content-bg': a.contentBg,
92 '--bkbg-tgl-icon-color': a.iconColor,
93 '--bkbg-tgl-icon-active-color': a.iconActiveColor,
94 '--bkbg-tgl-border-color': a.borderColor,
95 '--bkbg-tgl-divider-color': a.dividerColor
96 };
97 Object.assign(wrapStyle, _tvf(a.titleTypo, '--bktgl-tt-'), _tvf(a.contentTypo, '--bktgl-ct-'));
98
99 var blockProps = useBlockProps({
100 className: 'bkbg-tgl-wrap bkbg-tgl-editor' + (isOpen ? ' is-open' : ''),
101 style: wrapStyle,
102 'data-layout': a.layout,
103 'data-icon': a.iconType,
104 'data-icon-pos': a.iconPosition
105 });
106
107 var inspector = el(InspectorControls, {},
108
109 el(PanelBody, { title: __('Toggle Settings', 'blockenberg'), initialOpen: true },
110 el(ToggleControl, {
111 label: __('Open by default', 'blockenberg'),
112 help: __('Start the toggle in expanded state on page load.', 'blockenberg'),
113 checked: a.defaultOpen,
114 __nextHasNoMarginBottom: true,
115 onChange: function (v) { setAttributes({ defaultOpen: v }); }
116 }),
117 el(SelectControl, {
118 label: __('Title Tag', 'blockenberg'),
119 value: a.titleTag,
120 options: titleTagOptions,
121 onChange: function (v) { setAttributes({ titleTag: v }); }
122 })
123 ),
124
125 el(PanelBody, { title: __('Style', 'blockenberg'), initialOpen: false },
126 el(SelectControl, {
127 label: __('Layout', 'blockenberg'),
128 value: a.layout,
129 options: layoutOptions,
130 onChange: function (v) { setAttributes({ layout: v }); }
131 }),
132 el(SelectControl, {
133 label: __('Icon Type', 'blockenberg'),
134 value: a.iconType,
135 options: iconTypeOptions,
136 onChange: function (v) { setAttributes({ iconType: v }); }
137 }),
138 el(SelectControl, {
139 label: __('Icon Position', 'blockenberg'),
140 value: a.iconPosition,
141 options: iconPositionOptions,
142 onChange: function (v) { setAttributes({ iconPosition: v }); }
143 }),
144 el(RangeControl, {
145 label: __('Border Radius (px)', 'blockenberg'),
146 value: a.borderRadius,
147 min: 0, max: 24,
148 onChange: function (v) { setAttributes({ borderRadius: v }); }
149 }),
150 el(RangeControl, {
151 label: __('Padding (px)', 'blockenberg'),
152 value: a.padding,
153 min: 8, max: 48,
154 onChange: function (v) { setAttributes({ padding: v }); }
155 }),
156 el(RangeControl, {
157 label: __('Animation Speed (ms)', 'blockenberg'),
158 value: a.animationSpeed,
159 min: 0, max: 800, step: 50,
160 onChange: function (v) { setAttributes({ animationSpeed: v }); }
161 })
162 ),
163
164 el(PanelBody, { title: __('Typography', 'blockenberg'), initialOpen: false },
165 getTypoControl(props, 'titleTypo', __('Title', 'blockenberg')),
166 getTypoControl(props, 'contentTypo', __('Content', 'blockenberg'))
167 ),
168
169 el(PanelBody, { title: __('Colors', 'blockenberg'), initialOpen: false },
170 el(PanelColorSettings, {
171 title: __('Title Colors', 'blockenberg'),
172 initialOpen: false,
173 colorSettings: [
174 { value: a.titleColor, onChange: function (c) { setAttributes({ titleColor: c || '#111827' }); }, label: __('Text', 'blockenberg') },
175 { value: a.titleBg, onChange: function (c) { setAttributes({ titleBg: c || '#ffffff' }); }, label: __('Background', 'blockenberg') },
176 { value: a.titleHoverBg, onChange: function (c) { setAttributes({ titleHoverBg: c || '#f9fafb' }); }, label: __('Background (Hover)', 'blockenberg') },
177 { value: a.activeTitleColor, onChange: function (c) { setAttributes({ activeTitleColor: c || '#1d4ed8' }); }, label: __('Text (Open)', 'blockenberg') },
178 { value: a.activeTitleBg, onChange: function (c) { setAttributes({ activeTitleBg: c || '#eff6ff' }); }, label: __('Background (Open)', 'blockenberg') }
179 ]
180 }),
181 el(PanelColorSettings, {
182 title: __('Content Colors', 'blockenberg'),
183 initialOpen: false,
184 colorSettings: [
185 { value: a.contentColor, onChange: function (c) { setAttributes({ contentColor: c || '#374151' }); }, label: __('Text', 'blockenberg') },
186 { value: a.contentBg, onChange: function (c) { setAttributes({ contentBg: c || '#ffffff' }); }, label: __('Background', 'blockenberg') }
187 ]
188 }),
189 el(PanelColorSettings, {
190 title: __('Icon & Border Colors', 'blockenberg'),
191 initialOpen: false,
192 colorSettings: [
193 { value: a.iconColor, onChange: function (c) { setAttributes({ iconColor: c || '#6b7280' }); }, label: __('Icon', 'blockenberg') },
194 { value: a.iconActiveColor, onChange: function (c) { setAttributes({ iconActiveColor: c || '#2563eb' }); }, label: __('Icon (Open)', 'blockenberg') },
195 { value: a.borderColor, onChange: function (c) { setAttributes({ borderColor: c || '#e5e7eb' }); }, label: __('Border', 'blockenberg') },
196 { value: a.dividerColor, onChange: function (c) { setAttributes({ dividerColor: c || '#f3f4f6' }); }, label: __('Divider', 'blockenberg') }
197 ]
198 })
199 )
200 );
201
202 return el(Fragment, {},
203 inspector,
204 el('div', blockProps,
205 el('button', {
206 className: 'bkbg-tgl-trigger',
207 'aria-expanded': isOpen ? 'true' : 'false'
208 },
209 a.iconPosition === 'left' && getIconEl(a.iconType),
210 el(a.titleTag, { className: 'bkbg-tgl-title' },
211 el(TextControl, {
212 value: a.title,
213 onChange: function (v) { setAttributes({ title: v }); },
214 placeholder: __('Toggle title...', 'blockenberg'),
215 hideLabelFromVision: true,
216 label: __('Toggle Title', 'blockenberg')
217 })
218 ),
219 a.iconPosition === 'right' && getIconEl(a.iconType)
220 ),
221 el('div', { className: 'bkbg-tgl-content', 'aria-hidden': isOpen ? 'false' : 'true' },
222 el('div', { className: 'bkbg-tgl-content-inner' },
223 el(RichText, {
224 tagName: 'div',
225 className: 'bkbg-tgl-body',
226 value: a.content,
227 onChange: function (v) { setAttributes({ content: v }); },
228 placeholder: __('Add toggle content here...', 'blockenberg')
229 })
230 )
231 )
232 )
233 );
234 },
235
236 save: function (props) {
237 var a = props.attributes;
238 var RichTextContent = wp.blockEditor.RichText.Content;
239
240 var wrapParts = [
241 '--bkbg-tgl-radius:' + a.borderRadius + 'px',
242 '--bkbg-tgl-padding:' + a.padding + 'px',
243 '--bkbg-tgl-speed:' + a.animationSpeed + 'ms',
244 '--bkbg-tgl-title-color:' + a.titleColor,
245 '--bkbg-tgl-title-bg:' + a.titleBg,
246 '--bkbg-tgl-title-hover-bg:' + a.titleHoverBg,
247 '--bkbg-tgl-active-title-bg:' + a.activeTitleBg,
248 '--bkbg-tgl-active-title-color:' + a.activeTitleColor,
249 '--bkbg-tgl-content-color:' + a.contentColor,
250 '--bkbg-tgl-content-bg:' + a.contentBg,
251 '--bkbg-tgl-icon-color:' + a.iconColor,
252 '--bkbg-tgl-icon-active-color:' + a.iconActiveColor,
253 '--bkbg-tgl-border-color:' + a.borderColor,
254 '--bkbg-tgl-divider-color:' + a.dividerColor
255 ];
256 var tv = Object.assign({}, _tvf(a.titleTypo, '--bktgl-tt-'), _tvf(a.contentTypo, '--bktgl-ct-'));
257 Object.keys(tv).forEach(function (k) { wrapParts.push(k + ':' + tv[k]); });
258 var wrapStyle = wrapParts.join(';');
259
260 var iconSvgs = {
261 chevron: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"/></svg>',
262 plus: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>',
263 arrow: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="18" height="18" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="5" x2="12" y2="19"/><polyline points="19 12 12 19 5 12"/></svg>'
264 };
265
266 var iconEl = a.iconType !== 'none' ? el('span', {
267 className: 'bkbg-tgl-icon',
268 'aria-hidden': 'true',
269 dangerouslySetInnerHTML: { __html: iconSvgs[a.iconType] || iconSvgs.chevron }
270 }) : null;
271
272 var blockProps = wp.blockEditor.useBlockProps.save({
273 className: 'bkbg-tgl-wrap' + (a.defaultOpen ? ' is-open' : ''),
274 style: wrapStyle,
275 'data-layout': a.layout,
276 'data-icon': a.iconType,
277 'data-icon-pos': a.iconPosition,
278 'data-default-open': a.defaultOpen ? '1' : '0',
279 'data-speed': a.animationSpeed
280 });
281
282 return el('div', blockProps,
283 el('button', {
284 className: 'bkbg-tgl-trigger',
285 'aria-expanded': a.defaultOpen ? 'true' : 'false'
286 },
287 a.iconPosition === 'left' && iconEl,
288 el(a.titleTag, { className: 'bkbg-tgl-title' }, a.title),
289 a.iconPosition === 'right' && iconEl
290 ),
291 el('div', {
292 className: 'bkbg-tgl-content',
293 'aria-hidden': a.defaultOpen ? 'false' : 'true'
294 },
295 el('div', { className: 'bkbg-tgl-content-inner' },
296 el(RichTextContent, { tagName: 'div', className: 'bkbg-tgl-body', value: a.content })
297 )
298 )
299 );
300 }
301 });
302 }() );
303