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 / service-details / index.js

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

192 lines 13.6 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 __ = wp.i18n.__;
4 var registerBlockType = wp.blocks.registerBlockType;
5 var InspectorControls = wp.blockEditor.InspectorControls;
6 var MediaUpload = wp.blockEditor.MediaUpload;
7 var MediaUploadCheck = wp.blockEditor.MediaUploadCheck;
8 var useBlockProps = wp.blockEditor.useBlockProps;
9 var RichText = wp.blockEditor.RichText;
10 var PanelColorSettings = wp.blockEditor.PanelColorSettings;
11 var PanelBody = wp.components.PanelBody;
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 var Button = wp.components.Button;
17
18 var _tc, _tv;
19 function getTC() { return _tc || (_tc = window.bkbgTypographyControl); }
20 function getTV() { return _tv || (_tv = window.bkbgTypoCssVars); }
21
22 registerBlockType('blockenberg/service-details', {
23 edit: function (props) {
24 var attr = props.attributes;
25 var setAttr = props.setAttributes;
26 var blockProps = useBlockProps((function () {
27 var _tv = getTV();
28 var s = {};
29 Object.assign(s, _tv(attr.headingTypo, '--bksd-ht-'));
30 Object.assign(s, _tv(attr.eyebrowTypo, '--bksd-et-'));
31 Object.assign(s, _tv(attr.bodyTypo, '--bksd-bt-'));
32 return { className: 'bkbg-svd-editor', style: s };
33 })());
34
35 var isRight = attr.layout === 'image-right';
36 var isCentered = attr.layout === 'centered';
37
38 function updateFeature(idx, key, val) {
39 var next = attr.features.map(function (f, i) {
40 if (i !== idx) return f;
41 var obj = {}; Object.keys(f).forEach(function (k) { obj[k] = f[k]; });
42 obj[key] = val; return obj;
43 });
44 setAttr({ features: next });
45 }
46
47 function removeFeature(idx) {
48 setAttr({ features: attr.features.filter(function (_, i) { return i !== idx; }) });
49 }
50
51 /* image panel */
52 var imagePanel = el('div', { className: 'bkbg-svd-image-col', style: { flex: '0 0 48%' } },
53 el(MediaUploadCheck, {},
54 el(MediaUpload, {
55 onSelect: function (m) { setAttr({ imageUrl: m.url, imageId: m.id, imageAlt: m.alt || '' }); },
56 allowedTypes: ['image'], value: attr.imageId,
57 render: function (ref) {
58 return attr.imageUrl
59 ? el('div', { style: { position: 'relative' } },
60 el('img', {
61 src: attr.imageUrl, alt: attr.imageAlt,
62 style: { width: '100%', borderRadius: attr.imageRadius + 'px', display: 'block', maxHeight: '480px', objectFit: 'cover' }
63 }),
64 el(Button, {
65 isSmall: true, isDestructive: true,
66 style: { position: 'absolute', top: '8px', right: '8px' },
67 onClick: function () { setAttr({ imageUrl: '', imageId: 0 }); }
68 }, '')
69 )
70 : el('div', {
71 onClick: ref.open, style: { background: '#f3f4f6', borderRadius: attr.imageRadius + 'px', height: '320px', display: 'flex', alignItems: 'center', justifyContent: 'center', cursor: 'pointer', fontSize: '40px', color: '#d1d5db' }
72 }, '🖼️');
73 }
74 })
75 )
76 );
77
78 /* text panel */
79 var textPanel = el('div', { className: 'bkbg-svd-text-col', style: { flex: '1' } },
80 attr.showEyebrow && el(RichText, {
81 tagName: 'p', value: attr.eyebrow, className: 'bkbg-svd-eyebrow',
82 style: { color: attr.eyebrowColor, margin: '0 0 12px' },
83 onChange: function (v) { setAttr({ eyebrow: v }); }
84 }),
85 el(RichText, {
86 tagName: 'h2', value: attr.heading, className: 'bkbg-svd-heading',
87 style: { color: attr.headingColor, margin: '0 0 14px' },
88 onChange: function (v) { setAttr({ heading: v }); }
89 }),
90 el(RichText, {
91 tagName: 'p', value: attr.subtext, className: 'bkbg-svd-subtext',
92 style: { color: attr.bodyColor, margin: '0 0 12px' },
93 onChange: function (v) { setAttr({ subtext: v }); }
94 }),
95 el(RichText, {
96 tagName: 'p', value: attr.bodyText, className: 'bkbg-svd-body',
97 style: { color: attr.bodyColor, margin: '0 0 24px' },
98 onChange: function (v) { setAttr({ bodyText: v }); }
99 }),
100 attr.showFeatures && el('div', { style: { marginBottom: '28px' } },
101 attr.features.map(function (feat, idx) {
102 return el('div', {
103 key: idx,
104 style: { display: 'flex', alignItems: 'center', gap: '12px', marginBottom: '10px' }
105 },
106 el('span', {
107 style: { background: attr.checkBg, color: attr.checkColor, width: '26px', height: '26px', borderRadius: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: '13px', fontWeight: '700', flexShrink: 0 }
108 }, feat.icon || ''),
109 el(TextControl, {
110 value: feat.text,
111 style: { flex: 1, margin: 0 },
112 onChange: function (v) { updateFeature(idx, 'text', v); },
113 __nextHasNoMarginBottom: true
114 }),
115 el(Button, { isSmall: true, isDestructive: true, onClick: function () { removeFeature(idx); } }, '')
116 );
117 }),
118 el(Button, { isSecondary: true, isSmall: true, onClick: function () { setAttr({ features: attr.features.concat([{ icon: '', text: 'New feature' }]) }); } }, '+ Add feature')
119 ),
120 el('div', { style: { display: 'flex', gap: '12px', flexWrap: 'wrap', alignItems: 'center' } },
121 attr.ctaEnabled && el('a', { href: '#editor', style: { background: attr.ctaBg, color: attr.ctaColor, padding: '12px 28px', borderRadius: '6px', fontWeight: '600', fontSize: '15px', textDecoration: 'none', display: 'inline-block' } }, attr.ctaLabel),
122 attr.cta2Enabled && el('a', { href: '#editor', style: { color: attr.cta2Color, fontWeight: '600', fontSize: '15px', textDecoration: 'underline' } }, attr.cta2Label)
123 )
124 );
125
126 var controls = el(InspectorControls, {},
127 el(PanelBody, { title: __('Image & Layout', 'blockenberg'), initialOpen: true },
128 el(SelectControl, {
129 label: __('Layout', 'blockenberg'), value: attr.layout,
130 options: [{ label: 'Image left, text right', value: 'image-left' }, { label: 'Image right, text left', value: 'image-right' }, { label: 'Centered (image top)', value: 'centered' }],
131 onChange: function (v) { setAttr({ layout: v }); }, __nextHasNoMarginBottom: true
132 }),
133 el(RangeControl, { label: __('Image Border Radius (px)', 'blockenberg'), value: attr.imageRadius, min: 0, max: 32, onChange: function (v) { setAttr({ imageRadius: v }); }, __nextHasNoMarginBottom: true })
134 ),
135 el(PanelBody, { title: __('Text & CTAs', 'blockenberg'), initialOpen: false },
136 el(ToggleControl, { label: __('Show Eyebrow', 'blockenberg'), checked: attr.showEyebrow, onChange: function (v) { setAttr({ showEyebrow: v }); }, __nextHasNoMarginBottom: true }),
137 el(ToggleControl, { label: __('Show Feature List', 'blockenberg'), checked: attr.showFeatures, onChange: function (v) { setAttr({ showFeatures: v }); }, __nextHasNoMarginBottom: true }),
138 el(ToggleControl, { label: __('Show Primary CTA', 'blockenberg'), checked: attr.ctaEnabled, onChange: function (v) { setAttr({ ctaEnabled: v }); }, __nextHasNoMarginBottom: true }),
139 attr.ctaEnabled && el(TextControl, { label: __('CTA Label', 'blockenberg'), value: attr.ctaLabel, onChange: function (v) { setAttr({ ctaLabel: v }); }, __nextHasNoMarginBottom: true }),
140 attr.ctaEnabled && el(TextControl, { label: __('CTA URL', 'blockenberg'), value: attr.ctaUrl, onChange: function (v) { setAttr({ ctaUrl: v }); }, __nextHasNoMarginBottom: true }),
141 el(ToggleControl, { label: __('Show Secondary CTA', 'blockenberg'), checked: attr.cta2Enabled, onChange: function (v) { setAttr({ cta2Enabled: v }); }, __nextHasNoMarginBottom: true }),
142 attr.cta2Enabled && el(TextControl, { label: __('Secondary CTA Label', 'blockenberg'), value: attr.cta2Label, onChange: function (v) { setAttr({ cta2Label: v }); }, __nextHasNoMarginBottom: true }),
143 attr.cta2Enabled && el(TextControl, { label: __('Secondary CTA URL', 'blockenberg'), value: attr.cta2Url, onChange: function (v) { setAttr({ cta2Url: v }); }, __nextHasNoMarginBottom: true }),
144 el(RangeControl, { label: __('Max Width (px)', 'blockenberg'), value: attr.maxWidth, min: 480, max: 1600, onChange: function (v) { setAttr({ maxWidth: v }); }, __nextHasNoMarginBottom: true }),
145 el(RangeControl, { label: __('Padding Top (px)', 'blockenberg'), value: attr.paddingTop, min: 0, max: 160, onChange: function (v) { setAttr({ paddingTop: v }); }, __nextHasNoMarginBottom: true }),
146 el(RangeControl, { label: __('Padding Bottom (px)', 'blockenberg'), value: attr.paddingBottom, min: 0, max: 160, onChange: function (v) { setAttr({ paddingBottom: v }); }, __nextHasNoMarginBottom: true })
147 ),
148
149 el( PanelBody, { title: __( 'Typography', 'blockenberg' ), initialOpen: false },
150 el(getTC(), { label: __('Heading', 'blockenberg'), value: attr.headingTypo, onChange: function (v) { setAttr({ headingTypo: v }); } }),
151 el(getTC(), { label: __('Eyebrow', 'blockenberg'), value: attr.eyebrowTypo, onChange: function (v) { setAttr({ eyebrowTypo: v }); } }),
152 el(getTC(), { label: __('Body', 'blockenberg'), value: attr.bodyTypo, onChange: function (v) { setAttr({ bodyTypo: v }); } })
153 ),
154 el(PanelColorSettings, {
155 title: __('Colors', 'blockenberg'), initialOpen: false,
156 colorSettings: [
157 { label: __('Background', 'blockenberg'), value: attr.bgColor, onChange: function (v) { setAttr({ bgColor: v || '#ffffff' }); } },
158 { label: __('Eyebrow', 'blockenberg'), value: attr.eyebrowColor, onChange: function (v) { setAttr({ eyebrowColor: v || '#7c3aed' }); } },
159 { label: __('Heading', 'blockenberg'), value: attr.headingColor, onChange: function (v) { setAttr({ headingColor: v || '#111827' }); } },
160 { label: __('Body Text', 'blockenberg'), value: attr.bodyColor, onChange: function (v) { setAttr({ bodyColor: v || '#374151' }); } },
161 { label: __('Feature Text', 'blockenberg'), value: attr.featureColor, onChange: function (v) { setAttr({ featureColor: v || '#374151' }); } },
162 { label: __('Check BG', 'blockenberg'), value: attr.checkBg, onChange: function (v) { setAttr({ checkBg: v || '#ede9fe' }); } },
163 { label: __('Check Icon', 'blockenberg'), value: attr.checkColor, onChange: function (v) { setAttr({ checkColor: v || '#7c3aed' }); } },
164 { label: __('Primary CTA BG', 'blockenberg'), value: attr.ctaBg, onChange: function (v) { setAttr({ ctaBg: v || '#7c3aed' }); } },
165 { label: __('Primary CTA Text', 'blockenberg'), value: attr.ctaColor, onChange: function (v) { setAttr({ ctaColor: v || '#ffffff' }); } },
166 { label: __('Secondary CTA', 'blockenberg'), value: attr.cta2Color, onChange: function (v) { setAttr({ cta2Color: v || '#7c3aed' }); } }
167 ]
168 })
169 );
170
171 return el('div', blockProps, controls,
172 el('div', { style: { background: attr.bgColor, paddingTop: attr.paddingTop + 'px', paddingBottom: attr.paddingBottom + 'px' } },
173 el('div', {
174 style: {
175 maxWidth: attr.maxWidth + 'px', margin: '0 auto',
176 display: isCentered ? 'flex' : 'flex',
177 flexDirection: isCentered ? 'column' : (isRight ? 'row-reverse' : 'row'),
178 gap: '48px', alignItems: isCentered ? 'center' : 'center'
179 }
180 }, imagePanel, textPanel)
181 )
182 );
183 },
184
185 save: function (props) {
186 return el('div', wp.blockEditor.useBlockProps.save(),
187 el('div', { className: 'bkbg-svd-app', 'data-opts': JSON.stringify(props.attributes) })
188 );
189 }
190 });
191 }() );
192