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 / team-slider / index.js

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

210 lines 17.2 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; function getTypoControl() { return _tc || (_tc = window.bkbgTypographyControl); }
19 var _tv; function getTypoCssVars() { return _tv || (_tv = window.bkbgTypoCssVars); }
20
21 var CARD_STYLES = [
22 { value: 'default', label: 'Default (card)' },
23 { value: 'minimal', label: 'Minimal (no border)' },
24 { value: 'centered', label: 'Centered (avatar top-center)' },
25 { value: 'horizontal', label: 'Horizontal (avatar left)' }
26 ];
27
28 function emptyMember() {
29 return { name: '', role: '', bio: '', imageUrl: '', imageId: 0, imageAlt: '', tag: '', linkedin: '', twitter: '', email: '', website: '' };
30 }
31
32 registerBlockType('blockenberg/team-slider', {
33 edit: function (props) {
34 var attr = props.attributes;
35 var set = props.setAttributes;
36 var members = attr.members || [emptyMember()];
37
38 var blockProps = useBlockProps({ style: {
39 background: attr.bgColor || undefined,
40 paddingTop: attr.paddingTop + 'px',
41 paddingBottom: attr.paddingBottom + 'px'
42 }});
43
44 function updateMember(idx, field, val) {
45 var updated = members.map(function (m, i) {
46 if (i !== idx) return m;
47 var p = {}; p[field] = val;
48 return Object.assign({}, m, p);
49 });
50 set({ members: updated });
51 }
52
53 var isCentered = attr.cardStyle === 'centered';
54 var isHorizontal = attr.cardStyle === 'horizontal';
55
56 var controls = el(InspectorControls, {},
57 el(PanelBody, { title: __('Slider Settings', 'blockenberg'), initialOpen: true },
58 el(RangeControl, { label: __('Cards Visible', 'blockenberg'), value: attr.perView, min: 1, max: 4, __nextHasNoMarginBottom: true, onChange: function (v) { set({ perView: v }); } }),
59 el('div', { style: { marginTop: '8px' } },
60 el(ToggleControl, { label: __('Show Navigation Arrows', 'blockenberg'), checked: attr.showArrows, __nextHasNoMarginBottom: true, onChange: function (v) { set({ showArrows: v }); } })
61 ),
62 el('div', { style: { marginTop: '8px' } },
63 el(ToggleControl, { label: __('Show Dots', 'blockenberg'), checked: attr.showDots, __nextHasNoMarginBottom: true, onChange: function (v) { set({ showDots: v }); } })
64 ),
65 el('div', { style: { marginTop: '8px' } },
66 el(ToggleControl, { label: __('Autoplay', 'blockenberg'), checked: attr.autoplay, __nextHasNoMarginBottom: true, onChange: function (v) { set({ autoplay: v }); } })
67 ),
68 attr.autoplay && el('div', { style: { marginTop: '8px' } },
69 el(RangeControl, { label: __('Autoplay Delay (ms)', 'blockenberg'), value: attr.autoplayDelay, min: 1000, max: 10000, step: 500, __nextHasNoMarginBottom: true, onChange: function (v) { set({ autoplayDelay: v }); } })
70 )
71 ),
72 el(PanelBody, { title: __('Card Content', 'blockenberg'), initialOpen: false },
73 el(SelectControl, { label: __('Card Style', 'blockenberg'), value: attr.cardStyle, options: CARD_STYLES, __nextHasNoMarginBottom: true, onChange: function (v) { set({ cardStyle: v }); } }),
74 el('div', { style: { marginTop: '8px' } },
75 el(ToggleControl, { label: __('Show Bio', 'blockenberg'), checked: attr.showBio, __nextHasNoMarginBottom: true, onChange: function (v) { set({ showBio: v }); } })
76 ),
77 el('div', { style: { marginTop: '8px' } },
78 el(ToggleControl, { label: __('Show Social Links', 'blockenberg'), checked: attr.showSocials, __nextHasNoMarginBottom: true, onChange: function (v) { set({ showSocials: v }); } })
79 ),
80 el('div', { style: { marginTop: '8px' } },
81 el(ToggleControl, { label: __('Show Department Tag', 'blockenberg'), checked: attr.showTag, __nextHasNoMarginBottom: true, onChange: function (v) { set({ showTag: v }); } })
82 ),
83 el('div', { style: { marginTop: '10px' } },
84 el(RangeControl, { label: __('Avatar Size (px)', 'blockenberg'), value: attr.avatarSize, min: 40, max: 160, __nextHasNoMarginBottom: true, onChange: function (v) { set({ avatarSize: v }); } })
85 ),
86 el('div', { style: { marginTop: '10px' } },
87 el(RangeControl, { label: __('Avatar Radius %', 'blockenberg'), value: attr.avatarRadius, min: 0, max: 50, __nextHasNoMarginBottom: true, onChange: function (v) { set({ avatarRadius: v }); } })
88 ),
89 el('div', { style: { marginTop: '10px' } },
90 el(RangeControl, { label: __('Card Radius', 'blockenberg'), value: attr.cardRadius, min: 0, max: 30, __nextHasNoMarginBottom: true, onChange: function (v) { set({ cardRadius: v }); } })
91 )
92 ),
93 el(PanelBody, { title: __('Header & Spacing', 'blockenberg'), initialOpen: false },
94 el(ToggleControl, { label: __('Show Section Heading', 'blockenberg'), checked: attr.showHeading, __nextHasNoMarginBottom: true, onChange: function (v) { set({ showHeading: v }); } }),
95 attr.showHeading && el('div', { style: { marginTop: '8px' } },
96 el(TextControl, { label: __('Heading', 'blockenberg'), value: attr.heading, __nextHasNoMarginBottom: true, onChange: function (v) { set({ heading: v }); } })
97 ),
98 el('div', { style: { marginTop: '10px' } },
99 el(RangeControl, { label: __('Padding Top', 'blockenberg'), value: attr.paddingTop, min: 0, max: 120, __nextHasNoMarginBottom: true, onChange: function (v) { set({ paddingTop: v }); } })
100 ),
101 el('div', { style: { marginTop: '10px' } },
102 el(RangeControl, { label: __('Padding Bottom', 'blockenberg'), value: attr.paddingBottom, min: 0, max: 120, __nextHasNoMarginBottom: true, onChange: function (v) { set({ paddingBottom: v }); } })
103 )
104 ),
105 el(PanelColorSettings, {
106 title: __('Colors', 'blockenberg'), initialOpen: false,
107 colorSettings: [
108 { label: __('Section Background', 'blockenberg'), value: attr.bgColor, onChange: function (v) { set({ bgColor: v || '' }); } },
109 { label: __('Card Background', 'blockenberg'), value: attr.cardBg, onChange: function (v) { set({ cardBg: v || '#ffffff' }); } },
110 { label: __('Card Border', 'blockenberg'), value: attr.cardBorder, onChange: function (v) { set({ cardBorder: v || '#e5e7eb' }); } },
111 { label: __('Name', 'blockenberg'), value: attr.nameColor, onChange: function (v) { set({ nameColor: v || '#111827' }); } },
112 { label: __('Role', 'blockenberg'), value: attr.roleColor, onChange: function (v) { set({ roleColor: v || '#6366f1' }); } },
113 { label: __('Bio', 'blockenberg'), value: attr.bioColor, onChange: function (v) { set({ bioColor: v || '#6b7280' }); } },
114 { label: __('Tag Background', 'blockenberg'), value: attr.tagBg, onChange: function (v) { set({ tagBg: v || '#ede9fe' }); } },
115 { label: __('Tag Text', 'blockenberg'), value: attr.tagColor, onChange: function (v) { set({ tagColor: v || '#6366f1' }); } },
116 { label: __('Social Icons', 'blockenberg'), value: attr.socialColor, onChange: function (v) { set({ socialColor: v || '#6b7280' }); } },
117 { label: __('Dot', 'blockenberg'), value: attr.dotColor, onChange: function (v) { set({ dotColor: v || '#d1d5db' }); } },
118 { label: __('Dot Active', 'blockenberg'), value: attr.dotActive, onChange: function (v) { set({ dotActive: v || '#6366f1' }); } },
119 { label: __('Arrow Background', 'blockenberg'), value: attr.arrowBg, onChange: function (v) { set({ arrowBg: v || '#ffffff' }); } },
120 { label: __('Arrow Icon', 'blockenberg'), value: attr.arrowColor, onChange: function (v) { set({ arrowColor: v || '#374151' }); } }
121 ]
122 }),
123 el(PanelBody, { title: __('Typography', 'blockenberg'), initialOpen: false },
124 getTypoControl()({ label: __('Name', 'blockenberg'), value: attr.nameTypo, onChange: function (v) { set({ nameTypo: v }); } }),
125 getTypoControl()({ label: __('Bio', 'blockenberg'), value: attr.bioTypo, onChange: function (v) { set({ bioTypo: v }); } }),
126 el(RangeControl, { label: __('Heading Font Size (px)', 'blockenberg'), value: attr.headingFontSize, min: 18, max: 60, __nextHasNoMarginBottom: true, onChange: function (v) { set({ headingFontSize: v }); } }),
127 el(RangeControl, { label: __('Role Font Size (px)', 'blockenberg'), value: attr.roleFontSize, min: 10, max: 24, __nextHasNoMarginBottom: true, onChange: function (v) { set({ roleFontSize: v }); } })
128 )
129 );
130
131 /* editor preview: show all members as a grid */
132 function MemberCard(member, idx) {
133 var avatar = el('div', { style: { width: attr.avatarSize + 'px', height: attr.avatarSize + 'px', borderRadius: attr.avatarRadius + '%', overflow: 'hidden', background: '#e5e7eb', flexShrink: 0, position: 'relative' } },
134 member.imageUrl
135 ? el('img', { src: member.imageUrl, alt: member.imageAlt, style: { width: '100%', height: '100%', objectFit: 'cover' } })
136 : el('div', { style: { width: '100%', height: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: '12px', color: '#9ca3af' } }, '👤'),
137 el(MediaUploadCheck, {},
138 el(MediaUpload, {
139 onSelect: function (m) { updateMember(idx, 'imageUrl', m.url); updateMember(idx, 'imageId', m.id); updateMember(idx, 'imageAlt', m.alt || ''); },
140 allowedTypes: ['image'], value: member.imageId,
141 render: function (r) { return el(Button, { onClick: r.open, style: { position: 'absolute', inset: 0, background: 'rgba(0,0,0,0.3)', border: 'none', cursor: 'pointer', color: '#fff', fontSize: '11px', display: 'none' }, className: 'bkbg-ts-edit-overlay' }, ''); }
142 })
143 )
144 );
145
146 var content = el('div', { style: { flex: 1, textAlign: isCentered ? 'center' : undefined } },
147 attr.showTag && el(TextControl, { value: member.tag, label: '', placeholder: __('Dept…', 'blockenberg'), __nextHasNoMarginBottom: true, style: { fontSize: '11px', marginBottom: '6px' }, onChange: function (v) { updateMember(idx, 'tag', v); } }),
148 el(TextControl, { value: member.name, label: '', placeholder: __('Name', 'blockenberg'), __nextHasNoMarginBottom: true, style: { fontWeight: attr.nameFontWeight || 700, fontSize: (attr.nameFontSize || 17) + 'px', color: attr.nameColor }, onChange: function (v) { updateMember(idx, 'name', v); } }),
149 el(TextControl, { value: member.role, label: '', placeholder: __('Role', 'blockenberg'), __nextHasNoMarginBottom: true, style: { fontSize: (attr.roleFontSize || 13) + 'px', color: attr.roleColor }, onChange: function (v) { updateMember(idx, 'role', v); } }),
150 attr.showBio && el(RichText, { tagName: 'p', value: member.bio, allowedFormats: ['core/bold', 'core/italic'], placeholder: __('Bio…', 'blockenberg'), style: { fontSize: (attr.bioFontSize || 13) + 'px', lineHeight: attr.bioLineHeight || 1.6, color: attr.bioColor, margin: '8px 0' }, onChange: function (v) { updateMember(idx, 'bio', v); } }),
151 attr.showSocials && el('div', { style: { display: 'flex', gap: '8px', flexWrap: 'wrap', marginTop: '8px', justifyContent: isCentered ? 'center' : undefined } },
152 el(TextControl, { value: member.linkedin, label: '', placeholder: 'LinkedIn URL', __nextHasNoMarginBottom: true, style: { fontSize: '11px', width: '120px' }, onChange: function (v) { updateMember(idx, 'linkedin', v); } }),
153 el(TextControl, { value: member.twitter, label: '', placeholder: 'Twitter/X URL', __nextHasNoMarginBottom: true, style: { fontSize: '11px', width: '110px' }, onChange: function (v) { updateMember(idx, 'twitter', v); } }),
154 el(TextControl, { value: member.email, label: '', placeholder: 'Email', __nextHasNoMarginBottom: true, style: { fontSize: '11px', width: '120px' }, onChange: function (v) { updateMember(idx, 'email', v); } })
155 )
156 );
157
158 var cardContentChildren = isHorizontal
159 ? [el('div', { style: { display: 'flex', gap: '14px', alignItems: 'flex-start' } }, avatar, content)]
160 : [el('div', { style: { display: 'flex', justifyContent: isCentered ? 'center' : undefined, marginBottom: '12px' } }, avatar), content];
161
162 return el('div', {
163 key: idx,
164 style: {
165 background: attr.cardBg,
166 border: attr.cardStyle === 'minimal' ? 'none' : ('1px solid ' + attr.cardBorder),
167 borderRadius: attr.cardRadius + 'px',
168 padding: '20px',
169 position: 'relative'
170 }
171 },
172 cardContentChildren,
173 el('div', { style: { marginTop: '10px', display: 'flex', gap: '6px', justifyContent: 'flex-end' } },
174 el(Button, { isSmall: true, isDestructive: true, variant: 'tertiary', onClick: function () { set({ members: members.filter(function (_, i) { return i !== idx; }) }); } }, '× Remove')
175 )
176 );
177 }
178
179 return el('div', blockProps,
180 controls,
181 attr.showHeading && attr.heading && el('h2', { style: { fontWeight: 800, fontSize: (attr.headingFontSize || 28) + 'px', marginBottom: '24px', color: attr.nameColor } }, attr.heading),
182 el('div', { style: { display: 'grid', gridTemplateColumns: 'repeat(' + Math.min(attr.perView, members.length) + ', 1fr)', gap: '20px' } },
183 members.map(function (m, i) { return MemberCard(m, i); })
184 ),
185 el('div', { style: { marginTop: '16px', textAlign: 'center', display: 'flex', gap: '10px', justifyContent: 'center', alignItems: 'center' } },
186 attr.showArrows && el('span', { style: { display: 'inline-block', width: '36px', height: '36px', background: attr.arrowBg, border: '1px solid ' + attr.cardBorder, borderRadius: '50%', lineHeight: '34px', textAlign: 'center', cursor: 'pointer', color: attr.arrowColor } }, ''),
187 attr.showDots && members.map(function (_, i) { return el('span', { key: i, style: { display: 'inline-block', width: i === 0 ? '20px' : '8px', height: '8px', borderRadius: '999px', background: i === 0 ? attr.dotActive : attr.dotColor } }); }),
188 attr.showArrows && el('span', { style: { display: 'inline-block', width: '36px', height: '36px', background: attr.arrowBg, border: '1px solid ' + attr.cardBorder, borderRadius: '50%', lineHeight: '34px', textAlign: 'center', cursor: 'pointer', color: attr.arrowColor } }, '')
189 ),
190 el('div', { style: { marginTop: '12px', textAlign: 'center' } },
191 el(Button, { variant: 'primary', isSmall: true, onClick: function () { set({ members: members.concat([emptyMember()]) }); } }, '+ Add Member')
192 )
193 );
194 },
195 save: function (props) {
196 var attr = props.attributes;
197 var useBlockProps = wp.blockEditor.useBlockProps;
198 var _tvf = getTypoCssVars();
199 var s = {};
200 if (_tvf) {
201 Object.assign(s, _tvf(attr.nameTypo, '--bksl-nm-'));
202 Object.assign(s, _tvf(attr.bioTypo, '--bksl-bi-'));
203 }
204 return el('div', useBlockProps.save({ style: Object.keys(s).length ? s : undefined }),
205 el('div', { className: 'bkbg-ts-app', 'data-opts': JSON.stringify(attr) })
206 );
207 }
208 });
209 }() );
210