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 / lesson-objectives / index.js

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

220 lines 14.5 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 Button = wp.components.Button;
15
16 var _tc, _tv;
17 function getTypoControl() { return _tc || (_tc = window.bkbgTypographyControl); }
18 function getTypoCssVars() { return _tv || (_tv = window.bkbgTypoCssVars); }
19
20 var IP = function () { return window.bkbgIconPicker; };
21
22 var LEVELS = [
23 { value: 'beginner', label: '🟢 Beginner' },
24 { value: 'intermediate', label: '🟡 Intermediate' },
25 { value: 'advanced', label: '🔴 Advanced' },
26 { value: 'all', label: '🔵 All Levels' }
27 ];
28
29 var BULLET_OPTIONS = [
30 { value: 'check', label: '�
31 Checkmark' },
32 { value: 'arrow', label: '→ Arrow' },
33 { value: 'circle', label: '● Circle' },
34 { value: 'star', label: '�
35 Star' },
36 { value: 'custom', label: 'Custom' }
37 ];
38
39 var BULLETS = { check: '✓', arrow: '→', circle: '●', star: '�
40 ' };
41
42 function getBullet(attr) {
43 return attr.bulletStyle === 'custom' ? (attr.customBullet || '') : (BULLETS[attr.bulletStyle] || '');
44 }
45
46 function getLevelLabel(val) {
47 var found = LEVELS.find(function (l) { return l.value === val; });
48 return found ? found.label : val;
49 }
50
51 registerBlockType('blockenberg/lesson-objectives', {
52 edit: function (props) {
53 var attr = props.attributes;
54 var set = props.setAttributes;
55
56 var blockProps = useBlockProps((function () {
57 var _tvFn = getTypoCssVars();
58 var s = { padding: attr.paddingTop + 'px 0 ' + attr.paddingBottom + 'px' };
59 if (_tvFn) {
60 Object.assign(s, _tvFn(attr.headingTypo, '--bkbg-lob-h-'));
61 Object.assign(s, _tvFn(attr.objectiveTypo, '--bkbg-lob-o-'));
62 }
63 return { style: s };
64 })());
65 var bullet = getBullet(attr);
66
67 function updateObjective(idx, val) {
68 var arr = (attr.objectives || []).map(function (o, i) {
69 return i === idx ? { text: val } : o;
70 });
71 set({ objectives: arr });
72 }
73
74 var wrapStyle = {
75 background: attr.bgColor,
76 border: '1px solid ' + attr.borderColor,
77 borderRadius: attr.borderRadius + 'px',
78 padding: '20px 24px',
79 boxSizing: 'border-box'
80 };
81 if (attr.style === 'left-border') {
82 wrapStyle.borderLeft = '4px solid ' + attr.accentColor;
83 } else if (attr.style === 'top-border') {
84 wrapStyle.borderTop = '4px solid ' + attr.accentColor;
85 wrapStyle.borderRadius = '0 0 ' + attr.borderRadius + 'px ' + attr.borderRadius + 'px';
86 } else if (attr.style === 'minimal') {
87 wrapStyle.background = 'transparent';
88 wrapStyle.border = 'none';
89 wrapStyle.padding = '0';
90 }
91
92 /* Header row */
93 var header = el('div', { style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: '16px', flexWrap: 'wrap', gap: '8px' } },
94 el('div', { style: { display: 'flex', alignItems: 'center', gap: '10px' } },
95 attr.showIcon && el('span', { className: 'bkbg-lob-icon', style: { fontSize: '24px', lineHeight: 1 } }, IP().buildEditorIcon(attr.headingIconType, attr.headingIcon, attr.headingIconDashicon, attr.headingIconImageUrl, attr.headingIconDashiconColor)),
96 el(RichText, { tagName: 'h3', className: 'bkbg-lob-heading', value: attr.heading, allowedFormats: [], placeholder: __('What You\'ll Learn', 'blockenberg'), style: { margin: 0, color: attr.headingColor }, onChange: function (v) { set({ heading: v }); } })
97 ),
98 el('div', { style: { display: 'flex', alignItems: 'center', gap: '8px', flexWrap: 'wrap' } },
99 attr.showLevel && el('span', { style: { background: attr.levelBg, color: attr.levelColor, fontSize: '11px', padding: '3px 9px', borderRadius: '20px', fontWeight: 600 } }, getLevelLabel(attr.level)),
100 attr.showReadTime && attr.readTime && el('span', { style: { fontSize: '12px', color: attr.metaColor } }, '' + attr.readTime)
101 )
102 );
103
104 /* Objectives grid */
105 var cols = attr.columns > 1 ? 'repeat(' + attr.columns + ', 1fr)' : '1fr';
106 var listEl = el('div', { style: { display: 'grid', gridTemplateColumns: cols, gap: '10px' } },
107 (attr.objectives || []).map(function (obj, i) {
108 return el('div', { key: i, style: { display: 'flex', alignItems: 'flex-start', gap: '10px' } },
109 el('span', { style: { background: attr.bulletBg, color: attr.bulletColor, width: '24px', height: '24px', borderRadius: '50%', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: '13px', fontWeight: 700, flexShrink: 0, marginTop: '1px' } }, bullet),
110 el(RichText, { tagName: 'p', className: 'bkbg-lob-text', value: obj.text, allowedFormats: ['core/bold', 'core/italic'], placeholder: __('Objective…', 'blockenberg'), style: { margin: 0, color: attr.textColor }, onChange: function (v) { updateObjective(i, v); } })
111 );
112 })
113 );
114
115 var controls = el(InspectorControls, {},
116 el(PanelBody, { title: __('Objectives', 'blockenberg'), initialOpen: true },
117 (attr.objectives || []).map(function (obj, idx) {
118 return el('div', { key: idx, style: { display: 'flex', gap: '4px', marginBottom: '6px', alignItems: 'center' } },
119 el('div', { style: { flex: 1 } },
120 el(TextControl, { label: '', value: obj.text, placeholder: 'Objective…', __nextHasNoMarginBottom: true, onChange: function (v) { updateObjective(idx, v); } })
121 ),
122 el(Button, { variant: 'link', isDestructive: true, onClick: function () { set({ objectives: (attr.objectives || []).filter(function (_, i) { return i !== idx; }) }); } }, '')
123 );
124 }),
125 el(Button, { variant: 'secondary', style: { marginTop: '4px' }, onClick: function () { set({ objectives: (attr.objectives || []).concat([{ text: '' }]) }); } }, __('+ Add Objective', 'blockenberg'))
126 ),
127 el(PanelBody, { title: __('Header & Meta', 'blockenberg'), initialOpen: false },
128 el(IP().IconPickerControl, IP().iconPickerProps(attr, set, { charAttr: 'headingIcon', typeAttr: 'headingIconType', dashiconAttr: 'headingIconDashicon', imageUrlAttr: 'headingIconImageUrl', colorAttr: 'headingIconDashiconColor' })),
129 el('div', { style: { marginTop: '8px' } },
130 el(ToggleControl, { label: __('Show Icon', 'blockenberg'), checked: attr.showIcon, __nextHasNoMarginBottom: true, onChange: function (v) { set({ showIcon: v }); } })
131 ),
132 el('div', { style: { marginTop: '12px' } },
133 el(ToggleControl, { label: __('Show Level Badge', 'blockenberg'), checked: attr.showLevel, __nextHasNoMarginBottom: true, onChange: function (v) { set({ showLevel: v }); } })
134 ),
135 attr.showLevel && el('div', { style: { marginTop: '8px' } },
136 el(SelectControl, {
137 label: __('Level', 'blockenberg'), value: attr.level, __nextHasNoMarginBottom: true,
138 options: LEVELS.map(function (l) { return { label: l.label, value: l.value }; }),
139 onChange: function (v) { set({ level: v }); }
140 })
141 ),
142 el('div', { style: { marginTop: '12px' } },
143 el(ToggleControl, { label: __('Show Read Time', 'blockenberg'), checked: attr.showReadTime, __nextHasNoMarginBottom: true, onChange: function (v) { set({ showReadTime: v }); } })
144 ),
145 attr.showReadTime && el('div', { style: { marginTop: '8px' } },
146 el(TextControl, { label: __('Read Time', 'blockenberg'), value: attr.readTime, placeholder: '12 min read', __nextHasNoMarginBottom: true, onChange: function (v) { set({ readTime: v }); } })
147 )
148 ),
149 el(PanelBody, { title: __('Style', 'blockenberg'), initialOpen: false },
150 el(SelectControl, {
151 label: __('Style', 'blockenberg'), value: attr.style, __nextHasNoMarginBottom: true,
152 options: [{ label: 'Card (bordered)', value: 'card' }, { label: 'Left Border', value: 'left-border' }, { label: 'Top Border', value: 'top-border' }, { label: 'Minimal', value: 'minimal' }],
153 onChange: function (v) { set({ style: v }); }
154 }),
155 el('div', { style: { marginTop: '12px' } },
156 el(SelectControl, {
157 label: __('Bullet Style', 'blockenberg'), value: attr.bulletStyle, __nextHasNoMarginBottom: true,
158 options: BULLET_OPTIONS,
159 onChange: function (v) { set({ bulletStyle: v }); }
160 })
161 ),
162 attr.bulletStyle === 'custom' && el('div', { style: { marginTop: '8px' } },
163 el(TextControl, { label: __('Custom Bullet', 'blockenberg'), value: attr.customBullet, __nextHasNoMarginBottom: true, onChange: function (v) { set({ customBullet: v }); } })
164 ),
165 el('div', { style: { marginTop: '12px' } },
166 el(RangeControl, { label: __('Columns', 'blockenberg'), value: attr.columns, min: 1, max: 3, __nextHasNoMarginBottom: true, onChange: function (v) { set({ columns: v }); } })
167 ),
168 el('div', { style: { marginTop: '12px' } },
169 el(RangeControl, { label: __('Border Radius', 'blockenberg'), value: attr.borderRadius, min: 0, max: 20, __nextHasNoMarginBottom: true, onChange: function (v) { set({ borderRadius: v }); } })
170 ),
171 el('div', { style: { marginTop: '12px' } },
172 el(RangeControl, { label: __('Padding Top', 'blockenberg'), value: attr.paddingTop, min: 0, max: 120, __nextHasNoMarginBottom: true, onChange: function (v) { set({ paddingTop: v }); } })
173 ),
174 el('div', { style: { marginTop: '12px' } },
175 el(RangeControl, { label: __('Padding Bottom', 'blockenberg'), value: attr.paddingBottom, min: 0, max: 120, __nextHasNoMarginBottom: true, onChange: function (v) { set({ paddingBottom: v }); } })
176 )
177 ),
178 el(PanelColorSettings, {
179 title: __('Colors', 'blockenberg'), initialOpen: false,
180 colorSettings: [
181 { label: __('Background', 'blockenberg'), value: attr.bgColor, onChange: function (v) { set({ bgColor: v || '#f0fdf4' }); } },
182 { label: __('Border', 'blockenberg'), value: attr.borderColor, onChange: function (v) { set({ borderColor: v || '#86efac' }); } },
183 { label: __('Accent', 'blockenberg'), value: attr.accentColor, onChange: function (v) { set({ accentColor: v || '#16a34a' }); } },
184 { label: __('Heading', 'blockenberg'), value: attr.headingColor, onChange: function (v) { set({ headingColor: v || '#14532d' }); } },
185 { label: __('Bullet BG', 'blockenberg'), value: attr.bulletBg, onChange: function (v) { set({ bulletBg: v || '#dcfce7' }); } },
186 { label: __('Bullet Icon', 'blockenberg'), value: attr.bulletColor, onChange: function (v) { set({ bulletColor: v || '#16a34a' }); } },
187 { label: __('Item Text', 'blockenberg'), value: attr.textColor, onChange: function (v) { set({ textColor: v || '#166534' }); } },
188 { label: __('Meta Text', 'blockenberg'), value: attr.metaColor, onChange: function (v) { set({ metaColor: v || '#4b7a5a' }); } },
189 { label: __('Level Badge BG', 'blockenberg'), value: attr.levelBg, onChange: function (v) { set({ levelBg: v || '#16a34a' }); } },
190 { label: __('Level Badge Text', 'blockenberg'), value: attr.levelColor, onChange: function (v) { set({ levelColor: v || '#ffffff' }); } }
191 ]
192 }),
193 el(PanelBody, { title: 'Typography', initialOpen: false },
194 getTypoControl() && el(getTypoControl(), { label: __('Heading'), value: attr.headingTypo || {}, onChange: function (v) { set({ headingTypo: v }); } }),
195 getTypoControl() && el(getTypoControl(), { label: __('Objective'), value: attr.objectiveTypo || {}, onChange: function (v) { set({ objectiveTypo: v }); } })
196 ),
197
198 );
199
200 return el('div', blockProps,
201 controls,
202 el('div', { style: wrapStyle },
203 header,
204 listEl,
205 el('div', { style: { marginTop: '16px', paddingTop: '14px', borderTop: '1px solid ' + attr.borderColor, display: 'flex', justifyContent: 'flex-end' } },
206 el(Button, { variant: 'secondary', onClick: function () { set({ objectives: (attr.objectives || []).concat([{ text: '' }]) }); } }, __('+ Add Objective', 'blockenberg'))
207 )
208 )
209 );
210 },
211 save: function (props) {
212 var attr = props.attributes;
213 var useBlockProps = wp.blockEditor.useBlockProps;
214 return el('div', useBlockProps.save(),
215 el('div', { className: 'bkbg-lob-app', 'data-opts': JSON.stringify(attr) })
216 );
217 }
218 });
219 }() );
220