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 / research-brief / index.js

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

277 lines 20.3 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 registerBlockType = wp.blocks.registerBlockType;
5 var InspectorControls = wp.blockEditor.InspectorControls;
6 var useBlockProps = wp.blockEditor.useBlockProps;
7 var PanelBody = wp.components.PanelBody;
8 var PanelColorSettings = wp.blockEditor.PanelColorSettings;
9 var ToggleControl = wp.components.ToggleControl;
10 var RangeControl = wp.components.RangeControl;
11 var TextControl = wp.components.TextControl;
12 var TextareaControl = wp.components.TextareaControl;
13 var SelectControl = wp.components.SelectControl;
14 var Button = wp.components.Button;
15 var _tc; function getTypoControl() { return _tc || (_tc = window.bkbgTypographyControl); }
16 var _tv; function getTypoCssVars() { return _tv || (_tv = window.bkbgTypoCssVars); }
17
18 var studyTypeOptions = [
19 { label: '📊 Survey', value: 'survey' },
20 { label: '🔬 Experiment', value: 'experiment' },
21 { label: '📚 Meta-Analysis', value: 'meta-analysis'},
22 { label: '🗂️ Case Study', value: 'case-study' },
23 { label: '🔍 Literature Review', value: 'review' }
24 ];
25 var studyTypeLabels = {
26 'survey': '📊 Survey',
27 'experiment': '🔬 Experiment',
28 'meta-analysis':'📚 Meta-Analysis',
29 'case-study': '🗂️ Case Study',
30 'review': '🔍 Review'
31 };
32 var sigOptions = [
33 { label: '🟢 High Significance', value: 'high' },
34 { label: '🟡 Medium', value: 'medium' },
35 { label: '⚪ Low', value: 'low' }
36 ];
37
38 function upd(arr, idx, field, val) {
39 return arr.map(function (e, i) {
40 if (i !== idx) return e;
41 var u = {}; u[field] = val;
42 return Object.assign({}, e, u);
43 });
44 }
45
46 function sectionHead(label, a) {
47 return el('div', { style: { fontSize: 10, fontWeight: 700, textTransform: 'uppercase', letterSpacing: '.09em', color: a.accentColor, borderBottom: '2px solid ' + a.accentColor, paddingBottom: 5, marginBottom: 10 } }, label);
48 }
49
50 function sigBadgeStyle(sig, a) {
51 if (sig === 'high') return { background: a.highBg, color: a.highColor };
52 if (sig === 'medium') return { background: a.medBg, color: a.medColor };
53 return { background: a.lowBg, color: a.lowColor };
54 }
55 function sigLabel(sig) {
56 if (sig === 'high') return '🟢 High';
57 if (sig === 'medium') return '🟡 Medium';
58 return '⚪ Low';
59 }
60
61 registerBlockType('blockenberg/research-brief', {
62 edit: function (props) {
63 var a = props.attributes;
64 var set = props.setAttributes;
65 var TC = getTypoControl();
66 var blockProps = useBlockProps((function () {
67 var _tvFn = getTypoCssVars();
68 var s = {};
69 if (_tvFn) {
70 Object.assign(s, _tvFn(a.titleTypo || {}, '--bkrb-tt-'));
71 Object.assign(s, _tvFn(a.bodyTypo || {}, '--bkrb-bt-'));
72 }
73 return { className: 'bkbg-rb-editor-wrap', style: s };
74 })());
75
76 var preview = el('div', { className: 'bkbg-rb-wrap', style: { border: '1px solid ' + a.borderColor, borderRadius: a.borderRadius + 'px', overflow: 'hidden', background: a.bgColor } },
77 // Header
78 el('div', { style: { background: a.headerBg, padding: '20px 24px' } },
79 el('div', { style: { marginBottom: 10, display: 'flex', gap: 8, flexWrap: 'wrap', alignItems: 'center' } },
80 el('span', { style: { display: 'inline-block', padding: '3px 10px', borderRadius: 100, fontSize: 11, fontWeight: 700, background: a.typeBadgeBg, color: a.typeBadgeColor } }, studyTypeLabels[a.studyType] || a.studyType),
81 a.publicationYear && el('span', { style: { fontSize: 12, color: a.metaColor } }, a.publicationYear)
82 ),
83 el('h2', { className: 'bkbg-rb-title', style: { margin: '0 0 10px', color: a.headerColor } }, a.studyTitle),
84 el('div', { style: { display: 'flex', gap: 14, flexWrap: 'wrap' } },
85 a.authors && el('span', { style: { fontSize: 12, color: a.metaColor } }, '✍️ ' + a.authors),
86 a.publication && el('span', { style: { fontSize: 12, color: a.metaColor } }, '📰 ' + a.publication)
87 )
88 ),
89 // Meta strip — sample size
90 a.sampleSize && el('div', { style: { padding: '10px 24px', borderBottom: '1px solid ' + a.borderColor, background: '#f8fafc', fontSize: 12, color: '#374151' } },
91 el('strong', null, 'Sample: '), a.sampleSize
92 ),
93 // Body
94 el('div', { style: { padding: '18px 24px', display: 'grid', gap: 20 } },
95 // Methodology
96 a.showMethodology && a.methodology && el('div', null,
97 sectionHead('Methodology', a),
98 el('p', { className: 'bkbg-rb-method', style: { margin: 0, background: a.methodBg, borderRadius: 8, padding: '12px 14px', color: a.methodColor } }, a.methodology)
99 ),
100 // Findings
101 a.showFindings && a.findings.length > 0 && el('div', null,
102 sectionHead(a.findingsLabel, a),
103 el('div', { style: { display: 'grid', gap: 8 } },
104 a.findings.map(function (f, i) {
105 var bs = sigBadgeStyle(f.significance, a);
106 return el('div', { key: i, style: { display: 'flex', gap: 10, alignItems: 'flex-start', padding: '10px 12px', background: '#f8fafc', borderRadius: 8, borderLeft: '3px solid ' + a.accentColor } },
107 el('span', { style: { flexShrink: 0, padding: '2px 8px', borderRadius: 100, fontSize: 11, fontWeight: 700, background: bs.background, color: bs.color, whiteSpace: 'nowrap', marginTop: 1 } }, sigLabel(f.significance)),
108 el('p', { className: 'bkbg-rb-finding-text', style: { margin: 0, color: '#374151' } }, f.finding)
109 );
110 })
111 )
112 ),
113 // Limitations
114 a.showLimitations && a.limitations.length > 0 && el('div', null,
115 sectionHead(a.limitationsLabel, a),
116 el('ul', { style: { margin: 0, paddingLeft: 18, color: a.limitColor } },
117 a.limitations.map(function (l, i) { return el('li', { key: i, style: { marginBottom: 5 } }, l); })
118 )
119 ),
120 // Takeaways
121 a.showTakeaways && a.takeaways.length > 0 && el('div', null,
122 sectionHead(a.takeawaysLabel, a),
123 el('div', { style: { display: 'grid', gap: 6 } },
124 a.takeaways.map(function (t, i) {
125 return el('div', { key: i, style: { display: 'flex', gap: 10, alignItems: 'flex-start', padding: '10px 12px', background: a.takeawayBg, borderLeft: '3px solid ' + a.takeawayBorder, borderRadius: '0 6px 6px 0' } },
126 el('span', { style: { color: a.takeawayBorder, flexShrink: 0, fontWeight: 700 } }, ''),
127 el('span', { style: { color: a.takeawayColor } }, t)
128 );
129 })
130 )
131 ),
132 // Source
133 a.showSource && a.doi && el('div', { style: { fontSize: 12, color: a.metaColor, paddingTop: 8, borderTop: '1px solid ' + a.borderColor } },
134 el('span', null, 'DOI: '),
135 el('a', { href: a.sourceUrl || '#', style: { color: a.accentColor }, target: '_blank', rel: 'noopener' }, a.doi)
136 )
137 )
138 );
139
140 return el(Fragment, null,
141 el('div', blockProps, preview),
142 el(InspectorControls, null,
143 el(PanelBody, { title: 'Study Info', initialOpen: true },
144 el(TextareaControl, { label: 'Study Title', value: a.studyTitle, rows: 2, __nextHasNoMarginBottom: true, onChange: function (v) { set({ studyTitle: v }); } }),
145 el('div', { style: { marginTop: 8 } },
146 el(SelectControl, { label: 'Study Type', value: a.studyType, options: studyTypeOptions, __nextHasNoMarginBottom: true, onChange: function (v) { set({ studyType: v }); } })
147 ),
148 el('div', { style: { marginTop: 8, display: 'grid', gridTemplateColumns: '3fr 1fr', gap: 8 } },
149 el(TextControl, { label: 'Authors', value: a.authors, __nextHasNoMarginBottom: true, onChange: function (v) { set({ authors: v }); } }),
150 el(TextControl, { label: 'Year', value: a.publicationYear, __nextHasNoMarginBottom: true, onChange: function (v) { set({ publicationYear: v }); } })
151 ),
152 el('div', { style: { marginTop: 8 } },
153 el(TextControl, { label: 'Publication', value: a.publication, __nextHasNoMarginBottom: true, onChange: function (v) { set({ publication: v }); } })
154 ),
155 el('div', { style: { marginTop: 8 } },
156 el(TextControl, { label: 'Sample Size / Scope', value: a.sampleSize, __nextHasNoMarginBottom: true, onChange: function (v) { set({ sampleSize: v }); } })
157 )
158 ),
159 el(PanelBody, { title: 'Methodology', initialOpen: false },
160 el(ToggleControl, { label: 'Show Methodology', checked: a.showMethodology, __nextHasNoMarginBottom: true, onChange: function (v) { set({ showMethodology: v }); } }),
161 el('div', { style: { marginTop: 8 } },
162 el(TextareaControl, { label: 'Methodology', value: a.methodology, rows: 4, __nextHasNoMarginBottom: true, onChange: function (v) { set({ methodology: v }); } })
163 )
164 ),
165 el(PanelBody, { title: 'Findings', initialOpen: false },
166 el(ToggleControl, { label: 'Show Findings', checked: a.showFindings, __nextHasNoMarginBottom: true, onChange: function (v) { set({ showFindings: v }); } }),
167 el('div', { style: { marginTop: 8 } },
168 el(TextControl, { label: 'Section Label', value: a.findingsLabel, __nextHasNoMarginBottom: true, onChange: function (v) { set({ findingsLabel: v }); } })
169 ),
170 el('div', { style: { marginTop: 8 } },
171 a.findings.map(function (f, i) {
172 return el('div', { key: i, style: { marginBottom: 10, padding: '8px 10px', border: '1px solid #e5e7eb', borderRadius: 8, background: '#f8fafc' } },
173 el('div', { style: { display: 'flex', justifyContent: 'space-between', marginBottom: 6, alignItems: 'center' } },
174 el(SelectControl, { label: '', value: f.significance, options: sigOptions, __nextHasNoMarginBottom: true, onChange: function (v) { set({ findings: upd(a.findings, i, 'significance', v) }); } }),
175 el(Button, { isDestructive: true, variant: 'link', style: { fontSize: 11 }, onClick: function () { set({ findings: a.findings.filter(function (_, j) { return j !== i; }) }); } }, '')
176 ),
177 el(TextareaControl, { label: 'Finding', value: f.finding, rows: 2, __nextHasNoMarginBottom: true, onChange: function (v) { set({ findings: upd(a.findings, i, 'finding', v) }); } })
178 );
179 }),
180 el(Button, { variant: 'primary', style: { width: '100%', justifyContent: 'center', marginTop: 4 }, onClick: function () { set({ findings: a.findings.concat([{ finding: 'New finding.', significance: 'medium' }]) }); } }, '+ Add Finding')
181 )
182 ),
183 el(PanelBody, { title: 'Limitations', initialOpen: false },
184 el(ToggleControl, { label: 'Show Limitations', checked: a.showLimitations, __nextHasNoMarginBottom: true, onChange: function (v) { set({ showLimitations: v }); } }),
185 el('div', { style: { marginTop: 8 } },
186 el(TextControl, { label: 'Section Label', value: a.limitationsLabel, __nextHasNoMarginBottom: true, onChange: function (v) { set({ limitationsLabel: v }); } })
187 ),
188 el('div', { style: { marginTop: 8 } },
189 a.limitations.map(function (l, i) {
190 return el('div', { key: i, style: { display: 'flex', gap: 6, marginBottom: 6, alignItems: 'flex-start' } },
191 el(TextControl, { label: '', value: l, __nextHasNoMarginBottom: true, onChange: function (v) { set({ limitations: a.limitations.map(function (x, j) { return j === i ? v : x; }) }); } }),
192 el(Button, { isDestructive: true, variant: 'link', style: { flexShrink: 0 }, onClick: function () { set({ limitations: a.limitations.filter(function (_, j) { return j !== i; }) }); } }, '')
193 );
194 }),
195 el(Button, { variant: 'secondary', style: { width: '100%', justifyContent: 'center', marginTop: 4 }, onClick: function () { set({ limitations: a.limitations.concat(['New limitation']) }); } }, '+ Add Limitation')
196 )
197 ),
198 el(PanelBody, { title: 'Takeaways', initialOpen: false },
199 el(ToggleControl, { label: 'Show Takeaways', checked: a.showTakeaways, __nextHasNoMarginBottom: true, onChange: function (v) { set({ showTakeaways: v }); } }),
200 el('div', { style: { marginTop: 8 } },
201 el(TextControl, { label: 'Section Label', value: a.takeawaysLabel, __nextHasNoMarginBottom: true, onChange: function (v) { set({ takeawaysLabel: v }); } })
202 ),
203 el('div', { style: { marginTop: 8 } },
204 a.takeaways.map(function (t, i) {
205 return el('div', { key: i, style: { display: 'flex', gap: 6, marginBottom: 6, alignItems: 'flex-start' } },
206 el(TextControl, { label: '', value: t, __nextHasNoMarginBottom: true, onChange: function (v) { set({ takeaways: a.takeaways.map(function (x, j) { return j === i ? v : x; }) }); } }),
207 el(Button, { isDestructive: true, variant: 'link', style: { flexShrink: 0 }, onClick: function () { set({ takeaways: a.takeaways.filter(function (_, j) { return j !== i; }) }); } }, '')
208 );
209 }),
210 el(Button, { variant: 'secondary', style: { width: '100%', justifyContent: 'center', marginTop: 4 }, onClick: function () { set({ takeaways: a.takeaways.concat(['New takeaway']) }); } }, '+ Add Takeaway')
211 )
212 ),
213 el(PanelBody, { title: 'Source', initialOpen: false },
214 el(ToggleControl, { label: 'Show Source / DOI', checked: a.showSource, __nextHasNoMarginBottom: true, onChange: function (v) { set({ showSource: v }); } }),
215 el('div', { style: { marginTop: 8, display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 8 } },
216 el(TextControl, { label: 'DOI', value: a.doi, __nextHasNoMarginBottom: true, onChange: function (v) { set({ doi: v }); } }),
217 el(TextControl, { label: 'URL', value: a.sourceUrl, __nextHasNoMarginBottom: true, onChange: function (v) { set({ sourceUrl: v }); } })
218 )
219 ),
220 el(PanelBody, { title: 'Typography', initialOpen: false },
221 TC && el(TC, { label: 'Title', value: a.titleTypo || {}, onChange: function(v) { set({ titleTypo: v }); } }),
222 TC && el(TC, { label: 'Body Text', value: a.bodyTypo || {}, onChange: function(v) { set({ bodyTypo: v }); } }),
223 el('div', { style: { marginTop: 8 } },
224 el(RangeControl, { label: 'Border Radius (px)', value: a.borderRadius, min: 0, max: 24, __nextHasNoMarginBottom: true, onChange: function (v) { set({ borderRadius: v }); } })
225 )
226 ),
227 el(PanelColorSettings, {
228 title: 'Header Colors',
229 initialOpen: false,
230 colorSettings: [
231 { label: 'Header BG', value: a.headerBg, onChange: function (v) { set({ headerBg: v || '#0f172a' }); } },
232 { label: 'Header Text', value: a.headerColor, onChange: function (v) { set({ headerColor: v || '#f8fafc' }); } },
233 { label: 'Meta Text', value: a.metaColor, onChange: function (v) { set({ metaColor: v || '#94a3b8' }); } },
234 { label: 'Accent', value: a.accentColor, onChange: function (v) { set({ accentColor: v || '#0284c7' }); } },
235 { label: 'Block BG', value: a.bgColor, onChange: function (v) { set({ bgColor: v || '#ffffff' }); } },
236 { label: 'Border', value: a.borderColor, onChange: function (v) { set({ borderColor: v || '#e5e7eb' }); } }
237 ]
238 }),
239 el(PanelColorSettings, {
240 title: 'Significance Badge Colors',
241 initialOpen: false,
242 colorSettings: [
243 { label: 'High BG', value: a.highBg, onChange: function (v) { set({ highBg: v || '#dcfce7' }); } },
244 { label: 'High Text', value: a.highColor, onChange: function (v) { set({ highColor: v || '#14532d' }); } },
245 { label: 'Med BG', value: a.medBg, onChange: function (v) { set({ medBg: v || '#fef9c3' }); } },
246 { label: 'Med Text', value: a.medColor, onChange: function (v) { set({ medColor: v || '#713f12' }); } },
247 { label: 'Low BG', value: a.lowBg, onChange: function (v) { set({ lowBg: v || '#f1f5f9' }); } },
248 { label: 'Low Text', value: a.lowColor, onChange: function (v) { set({ lowColor: v || '#374151' }); } }
249 ]
250 }),
251 el(PanelColorSettings, {
252 title: 'Section Colors',
253 initialOpen: false,
254 colorSettings: [
255 { label: 'Method BG', value: a.methodBg, onChange: function (v) { set({ methodBg: v || '#f0f9ff' }); } },
256 { label: 'Limitations', value: a.limitColor, onChange: function (v) { set({ limitColor: v || '#7c3aed' }); } },
257 { label: 'Takeaway BG', value: a.takeawayBg, onChange: function (v) { set({ takeawayBg: v || '#f0fdf4' }); } },
258 { label: 'Takeaway Border',value: a.takeawayBorder,onChange: function (v) { set({ takeawayBorder: v || '#16a34a' }); } },
259 { label: 'Takeaway Text', value: a.takeawayColor, onChange: function (v) { set({ takeawayColor: v || '#166534' }); } }
260 ]
261 })
262 )
263 );
264 },
265
266 save: function (props) {
267 var useBlockProps = wp.blockEditor.useBlockProps;
268 return wp.element.createElement('div', useBlockProps.save(),
269 wp.element.createElement('div', {
270 className: 'bkbg-research-brief-app',
271 'data-opts': JSON.stringify(props.attributes)
272 })
273 );
274 }
275 });
276 }() );
277