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 / speaker-lineup / index.js

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

221 lines 15.1 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 useBlockProps = wp.blockEditor.useBlockProps;
7 var RichText = wp.blockEditor.RichText;
8 var PanelColorSettings = wp.blockEditor.PanelColorSettings;
9 var PanelBody = wp.components.PanelBody;
10 var ToggleControl = wp.components.ToggleControl;
11 var RangeControl = wp.components.RangeControl;
12 var SelectControl = wp.components.SelectControl;
13 var TextControl = wp.components.TextControl;
14 var TextareaControl = wp.components.TextareaControl;
15 var Button = wp.components.Button;
16
17 var _tc; function getTypoControl() { return _tc || (_tc = window.bkbgTypographyControl); }
18 var _tv; function getTypoCssVars() { return _tv || (_tv = window.bkbgTypoCssVars); }
19
20 registerBlockType('blockenberg/speaker-lineup', {
21 edit: function (props) {
22 var attr = props.attributes;
23 var setAttr = props.setAttributes;
24
25 function updateSpeaker(idx, key, val) {
26 var speakers = (attr.speakers || []).map(function (s, i) {
27 return i === idx ? Object.assign({}, s, {[key]: val}) : s;
28 });
29 setAttr({ speakers: speakers });
30 }
31
32 function addSpeaker() {
33 setAttr({ speakers: (attr.speakers || []).concat([{ name: 'New Speaker', title: 'Title', company: 'Company', topic: 'Topic', bio: 'Speaker bio...', avatarUrl: '', twitterUrl: '', linkedinUrl: '' }]) });
34 }
35
36 function removeSpeaker(idx) {
37 setAttr({ speakers: (attr.speakers || []).filter(function (_, i) { return i !== idx; }) });
38 }
39
40 var inspector = el(InspectorControls, null,
41 el(PanelBody, { title: __('Layout', 'blockenberg'), initialOpen: true },
42 el(SelectControl, {
43 __nextHasNoMarginBottom: true,
44 label: __('Layout', 'blockenberg'),
45 value: attr.layout,
46 options: [
47 { label: 'Grid', value: 'grid' },
48 { label: 'List (horizontal card)', value: 'list' },
49 { label: 'Featured (large first)', value: 'featured' }
50 ],
51 onChange: function (v) { setAttr({ layout: v }); }
52 }),
53 el(SelectControl, {
54 __nextHasNoMarginBottom: true,
55 label: __('Card Style', 'blockenberg'),
56 value: attr.cardStyle,
57 options: [
58 { label: 'Card (elevated)', value: 'card' },
59 { label: 'Bordered', value: 'bordered' },
60 { label: 'Clean (no border)', value: 'clean' }
61 ],
62 onChange: function (v) { setAttr({ cardStyle: v }); }
63 }),
64 el(RangeControl, {
65 __nextHasNoMarginBottom: true,
66 label: __('Columns (grid)', 'blockenberg'),
67 value: attr.columns,
68 min: 1, max: 4,
69 onChange: function (v) { setAttr({ columns: v }); }
70 }),
71 el(RangeControl, {
72 __nextHasNoMarginBottom: true,
73 label: __('Max Width (px)', 'blockenberg'),
74 value: attr.maxWidth, min: 600, max: 1600,
75 onChange: function (v) { setAttr({ maxWidth: v }); }
76 }),
77 el(RangeControl, {
78 __nextHasNoMarginBottom: true,
79 label: __('Padding Top (px)', 'blockenberg'),
80 value: attr.paddingTop, min: 0, max: 200,
81 onChange: function (v) { setAttr({ paddingTop: v }); }
82 }),
83 el(RangeControl, {
84 __nextHasNoMarginBottom: true,
85 label: __('Padding Bottom (px)', 'blockenberg'),
86 value: attr.paddingBottom, min: 0, max: 200,
87 onChange: function (v) { setAttr({ paddingBottom: v }); }
88 })
89 ),
90 el(PanelBody, { title: __('Card Content', 'blockenberg'), initialOpen: false },
91 el(ToggleControl, {
92 __nextHasNoMarginBottom: true,
93 label: __('Show Bio', 'blockenberg'),
94 checked: attr.showBio,
95 onChange: function (v) { setAttr({ showBio: v }); }
96 }),
97 el(ToggleControl, {
98 __nextHasNoMarginBottom: true,
99 label: __('Show Topic Badge', 'blockenberg'),
100 checked: attr.showTopic,
101 onChange: function (v) { setAttr({ showTopic: v }); }
102 }),
103 el(ToggleControl, {
104 __nextHasNoMarginBottom: true,
105 label: __('Show Social Links', 'blockenberg'),
106 checked: attr.showSocials,
107 onChange: function (v) { setAttr({ showSocials: v }); }
108 })
109 ),
110 el(PanelBody, { title: __('Speakers', 'blockenberg'), initialOpen: false },
111 (attr.speakers || []).map(function (speaker, idx) {
112 return el(PanelBody, { key: idx, title: (speaker.name || 'Speaker ' + (idx + 1)), initialOpen: false },
113 el(TextControl, { __nextHasNoMarginBottom: true, label: __('Name', 'blockenberg'), value: speaker.name, onChange: function (v) { updateSpeaker(idx, 'name', v); } }),
114 el(TextControl, { __nextHasNoMarginBottom: true, label: __('Title', 'blockenberg'), value: speaker.title, onChange: function (v) { updateSpeaker(idx, 'title', v); } }),
115 el(TextControl, { __nextHasNoMarginBottom: true, label: __('Company', 'blockenberg'), value: speaker.company, onChange: function (v) { updateSpeaker(idx, 'company', v); } }),
116 el(TextControl, { __nextHasNoMarginBottom: true, label: __('Talk Topic', 'blockenberg'), value: speaker.topic, onChange: function (v) { updateSpeaker(idx, 'topic', v); } }),
117 el(TextareaControl, { __nextHasNoMarginBottom: true, label: __('Bio', 'blockenberg'), value: speaker.bio, onChange: function (v) { updateSpeaker(idx, 'bio', v); } }),
118 el(TextControl, { __nextHasNoMarginBottom: true, label: __('Avatar URL', 'blockenberg'), value: speaker.avatarUrl, onChange: function (v) { updateSpeaker(idx, 'avatarUrl', v); } }),
119 el(TextControl, { __nextHasNoMarginBottom: true, label: __('Twitter URL', 'blockenberg'), value: speaker.twitterUrl, onChange: function (v) { updateSpeaker(idx, 'twitterUrl', v); } }),
120 el(TextControl, { __nextHasNoMarginBottom: true, label: __('LinkedIn URL', 'blockenberg'), value: speaker.linkedinUrl, onChange: function (v) { updateSpeaker(idx, 'linkedinUrl', v); } }),
121 el(Button, { isDestructive: true, variant: 'secondary', onClick: function () { removeSpeaker(idx); } }, __('Remove Speaker', 'blockenberg'))
122 );
123 }),
124 el(Button, { isPrimary: true, variant: 'primary', onClick: addSpeaker }, __('+ Add Speaker', 'blockenberg'))
125 ),
126 el(PanelColorSettings, {
127 title: __('Colors', 'blockenberg'),
128 initialOpen: false,
129 colorSettings: [
130 { label: __('Background', 'blockenberg'), value: attr.bgColor, onChange: function (v) { setAttr({ bgColor: v || '#ffffff' }); } },
131 { label: __('Heading', 'blockenberg'), value: attr.headingColor, onChange: function (v) { setAttr({ headingColor: v || '#111827' }); } },
132 { label: __('Subtext', 'blockenberg'), value: attr.subColor, onChange: function (v) { setAttr({ subColor: v || '#6b7280' }); } },
133 { label: __('Eyebrow', 'blockenberg'), value: attr.eyebrowColor, onChange: function (v) { setAttr({ eyebrowColor: v || '#6366f1' }); } },
134 { label: __('Card Background', 'blockenberg'), value: attr.cardBg, onChange: function (v) { setAttr({ cardBg: v || '#f8fafc' }); } },
135 { label: __('Card Border', 'blockenberg'), value: attr.cardBorder, onChange: function (v) { setAttr({ cardBorder: v || '#e2e8f0' }); } },
136 { label: __('Speaker Name', 'blockenberg'), value: attr.nameColor, onChange: function (v) { setAttr({ nameColor: v || '#111827' }); } },
137 { label: __('Speaker Title', 'blockenberg'), value: attr.titleColor, onChange: function (v) { setAttr({ titleColor: v || '#6b7280' }); } },
138 { label: __('Topic Badge BG', 'blockenberg'), value: attr.topicBg, onChange: function (v) { setAttr({ topicBg: v || '#ede9fe' }); } },
139 { label: __('Topic Badge Text', 'blockenberg'), value: attr.topicColor, onChange: function (v) { setAttr({ topicColor: v || '#5b21b6' }); } },
140 { label: __('Bio Text', 'blockenberg'), value: attr.bioColor, onChange: function (v) { setAttr({ bioColor: v || '#4b5563' }); } },
141 { label: __('Social Icons', 'blockenberg'), value: attr.socialColor, onChange: function (v) { setAttr({ socialColor: v || '#6366f1' }); } }
142 ]
143 }),
144 el(PanelBody, { title: __('Typography', 'blockenberg'), initialOpen: false },
145 getTypoControl() ? el(getTypoControl(), { label: __('Eyebrow Typography', 'blockenberg'), value: attr.eyebrowTypo || {}, onChange: function (v) { setAttr({ eyebrowTypo: v }); } }) : null,
146 getTypoControl() ? el(getTypoControl(), { label: __('Heading Typography', 'blockenberg'), value: attr.headingTypo || {}, onChange: function (v) { setAttr({ headingTypo: v }); } }) : null,
147 getTypoControl() ? el(getTypoControl(), { label: __('Subtext Typography', 'blockenberg'), value: attr.subtextTypo || {}, onChange: function (v) { setAttr({ subtextTypo: v }); } }) : null,
148 getTypoControl() ? el(getTypoControl(), { label: __('Name Typography', 'blockenberg'), value: attr.nameTypo || {}, onChange: function (v) { setAttr({ nameTypo: v }); } }) : null,
149 getTypoControl() ? el(getTypoControl(), { label: __('Description Typography', 'blockenberg'), value: attr.descTypo || {}, onChange: function (v) { setAttr({ descTypo: v }); } }) : null
150 )
151 );
152
153 var blockProps = useBlockProps((function () {
154 var s = { className: 'bkbg-spk-editor' };
155 var tv = getTypoCssVars();
156 if (tv) {
157 var st = {};
158 Object.assign(st, tv(attr.eyebrowTypo, '--bkspk-ey-'));
159 Object.assign(st, tv(attr.headingTypo, '--bkspk-hd-'));
160 Object.assign(st, tv(attr.subtextTypo, '--bkspk-st-'));
161 Object.assign(st, tv(attr.nameTypo, '--bkspk-nm-'));
162 Object.assign(st, tv(attr.descTypo, '--bkspk-ds-'));
163 s.style = st;
164 }
165 return s;
166 })());
167
168 /* Preview grid */
169 return el('div', blockProps,
170 inspector,
171 el('div', { style: { background: attr.bgColor, padding: '40px', borderRadius: '8px', fontFamily: 'sans-serif' } },
172 el('div', { style: { textAlign: 'center', marginBottom: '40px' } },
173 el(RichText, {
174 tagName: 'p', value: attr.eyebrow,
175 onChange: function (v) { setAttr({ eyebrow: v }); },
176 placeholder: __('Eyebrow…', 'blockenberg'),
177 className: 'bkbg-spk-eyebrow',
178 style: { color: attr.eyebrowColor, margin: '0 0 8px' }
179 }),
180 el(RichText, {
181 tagName: 'h2', value: attr.heading,
182 onChange: function (v) { setAttr({ heading: v }); },
183 placeholder: __('Section heading…', 'blockenberg'),
184 className: 'bkbg-spk-heading',
185 style: { color: attr.headingColor, margin: '0 0 12px' }
186 }),
187 el(RichText, {
188 tagName: 'p', value: attr.subtext,
189 onChange: function (v) { setAttr({ subtext: v }); },
190 placeholder: __('Subtext…', 'blockenberg'),
191 className: 'bkbg-spk-sub',
192 style: { color: attr.subColor, maxWidth: '600px', margin: '0 auto' }
193 })
194 ),
195 el('div', { style: { display: 'grid', gridTemplateColumns: 'repeat(' + attr.columns + ',1fr)', gap: '24px' } },
196 (attr.speakers || []).map(function (s, i) {
197 return el('div', { key: i, style: { background: attr.cardBg, border: '1px solid ' + attr.cardBorder, borderRadius: '12px', padding: '24px', textAlign: 'center' } },
198 el('div', { style: { width: '80px', height: '80px', borderRadius: '50%', background: attr.accentColor, margin: '0 auto 12px', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: '28px', color: '#fff', overflow: 'hidden' } },
199 s.avatarUrl ? el('img', { src: s.avatarUrl, style: { width: '100%', height: '100%', objectFit: 'cover' } }) : '👤'
200 ),
201 el('div', { className: 'bkbg-spk-name', style: { color: attr.nameColor } }, s.name),
202 el('div', { className: 'bkbg-spk-title-co', style: { color: attr.titleColor, marginTop: '2px' } }, s.title + (s.company ? ' · ' + s.company : '')),
203 attr.showTopic && s.topic && el('div', { style: { display: 'inline-block', background: attr.topicBg, color: attr.topicColor, fontSize: '12px', fontWeight: 600, borderRadius: '20px', padding: '3px 10px', marginTop: '8px' } }, s.topic),
204 attr.showBio && s.bio && el('p', { className: 'bkbg-spk-bio', style: { color: attr.bioColor, marginTop: '10px' } }, s.bio)
205 );
206 })
207 )
208 )
209 );
210 },
211
212 save: function (props) {
213 var attr = props.attributes;
214 var useBlockProps = wp.blockEditor.useBlockProps;
215 return el('div', useBlockProps.save(),
216 el('div', { className: 'bkbg-spk-app', 'data-opts': JSON.stringify(attr) })
217 );
218 }
219 });
220 }() );
221