PluginProbe
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor / 2.0.8
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor v2.0.8
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 / api-reference / index.js

index.js in Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor 2.0.8, at blocks/api-reference/index.js

493 lines 22.8 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 __ = wp.i18n.__;
5 var useState = wp.element.useState;
6 var registerBlockType = wp.blocks.registerBlockType;
7 var InspectorControls = wp.blockEditor.InspectorControls;
8 var useBlockProps = wp.blockEditor.useBlockProps;
9 var PanelBody = wp.components.PanelBody;
10 var PanelColorSettings = wp.blockEditor.PanelColorSettings;
11 var ToggleControl = wp.components.ToggleControl;
12 var RangeControl = wp.components.RangeControl;
13 var SelectControl = wp.components.SelectControl;
14 var TextControl = wp.components.TextControl;
15 var TextareaControl = wp.components.TextareaControl;
16 var Button = wp.components.Button;
17
18 var _TypographyControl, _typoCssVars;
19 function getTypographyControl() { return _TypographyControl || (_TypographyControl = window.bkbgTypographyControl); }
20 function getTypoCssVars() { return _typoCssVars || (_typoCssVars = window.bkbgTypoCssVars); }
21
22 var METHOD_COLORS = {
23 GET: { bg: '#22c55e', color: '#fff' },
24 POST: { bg: '#3b82f6', color: '#fff' },
25 PUT: { bg: '#f59e0b', color: '#fff' },
26 PATCH: { bg: '#8b5cf6', color: '#fff' },
27 DELETE: { bg: '#ef4444', color: '#fff' }
28 };
29
30 var AUTH_LABELS = {
31 none: 'No Auth',
32 bearer: 'Bearer Token',
33 'api-key': 'API Key',
34 basic: 'Basic Auth'
35 };
36
37 function updateParam(params, idx, field, val) {
38 return params.map(function (p, i) {
39 if (i !== idx) return p;
40 var upd = {}; upd[field] = val;
41 return Object.assign({}, p, upd);
42 });
43 }
44
45 function ParamEditor(props) {
46 var p = props.param;
47 var idx = props.idx;
48 var onChange = props.onChange;
49 var onRemove = props.onRemove;
50 var onMove = props.onMove;
51 var total = props.total;
52
53 var locationOpts = [
54 { label: 'Path', value: 'path' },
55 { label: 'Query', value: 'query' },
56 { label: 'Body', value: 'body' },
57 { label: 'Header', value: 'header' }
58 ];
59 var typeOpts = [
60 { label: 'string', value: 'string' },
61 { label: 'integer', value: 'integer' },
62 { label: 'number', value: 'number' },
63 { label: 'boolean', value: 'boolean' },
64 { label: 'array', value: 'array' },
65 { label: 'object', value: 'object' }
66 ];
67
68 return el('div', { className: 'bkbg-apir-param-editor' },
69 el('div', { className: 'bkbg-apir-param-header' },
70 el('strong', {}, p.name || '(unnamed)'),
71 el('span', { className: 'bkbg-apir-param-loc' }, p.location),
72 p.required && el('span', { className: 'bkbg-apir-req-badge' }, 'required'),
73 el('div', { style: { marginLeft: 'auto', display: 'flex', gap: '4px' } },
74 idx > 0 && el(Button, { isSmall: true, onClick: function () { onMove(idx, idx - 1); } }, ''),
75 idx < total - 1 && el(Button, { isSmall: true, onClick: function () { onMove(idx, idx + 1); } }, ''),
76 el(Button, { isSmall: true, isDestructive: true, onClick: onRemove }, '')
77 )
78 ),
79 el(TextControl, {
80 label: __('Name', 'blockenberg'),
81 value: p.name,
82 __nextHasNoMarginBottom: true,
83 onChange: function (v) { onChange(idx, 'name', v); }
84 }),
85 el(SelectControl, {
86 label: __('Location', 'blockenberg'),
87 value: p.location,
88 options: locationOpts,
89 __nextHasNoMarginBottom: true,
90 onChange: function (v) { onChange(idx, 'location', v); }
91 }),
92 el(SelectControl, {
93 label: __('Type', 'blockenberg'),
94 value: p.type,
95 options: typeOpts,
96 __nextHasNoMarginBottom: true,
97 onChange: function (v) { onChange(idx, 'type', v); }
98 }),
99 el(ToggleControl, {
100 label: __('Required', 'blockenberg'),
101 checked: p.required,
102 __nextHasNoMarginBottom: true,
103 onChange: function (v) { onChange(idx, 'required', v); }
104 }),
105 el(TextControl, {
106 label: __('Description', 'blockenberg'),
107 value: p.description,
108 __nextHasNoMarginBottom: true,
109 onChange: function (v) { onChange(idx, 'description', v); }
110 }),
111 el(TextControl, {
112 label: __('Example', 'blockenberg'),
113 value: p.example,
114 __nextHasNoMarginBottom: true,
115 onChange: function (v) { onChange(idx, 'example', v); }
116 })
117 );
118 }
119
120 function ApiPreview(props) {
121 var a = props.a;
122 var setAttributes = props.setAttributes;
123 var tab = props.tab;
124 var setTab = props.setTab;
125 var editField = props.editField;
126 var setEditField = props.setEditField;
127
128 var mc = METHOD_COLORS[a.method] || METHOD_COLORS.GET;
129 var codeBg = a.codeTheme === 'dark' ? '#1e1e2e' : '#f8fafc';
130 var codeColor = a.codeTheme === 'dark' ? '#a9b1d6' : '#334155';
131
132 // Header row
133 var headerEl = el('div', {
134 className: 'bkbg-apir-header',
135 style: { background: a.headerBg, color: a.headerColor }
136 },
137 el('span', {
138 className: 'bkbg-apir-method',
139 style: { background: mc.bg, color: mc.color }
140 }, a.method),
141 a.showBaseUrl && el('span', { className: 'bkbg-apir-base-url' }, a.baseUrl),
142 editField === 'endpoint'
143 ? el('input', {
144 type: 'text',
145 className: 'bkbg-apir-endpoint-input',
146 value: a.endpoint,
147 autoFocus: true,
148 onChange: function (e) { setAttributes({ endpoint: e.target.value }); },
149 onBlur: function () { setEditField(null); },
150 onKeyDown: function (e) { if (e.key === 'Enter') setEditField(null); }
151 })
152 : el('span', {
153 className: 'bkbg-apir-endpoint bkbg-apir-clickable',
154 onClick: function () { setEditField('endpoint'); }
155 }, a.endpoint),
156 a.showAuth && el('span', {
157 className: 'bkbg-apir-auth-badge'
158 }, AUTH_LABELS[a.authType] || a.authType)
159 );
160
161 // Title + description
162 var titleEl = editField === 'title'
163 ? el('input', {
164 type: 'text',
165 className: 'bkbg-apir-title-input',
166 value: a.title,
167 autoFocus: true,
168 onChange: function (e) { setAttributes({ title: e.target.value }); },
169 onBlur: function () { setEditField(null); },
170 onKeyDown: function (e) { if (e.key === 'Enter') setEditField(null); }
171 })
172 : el('h3', {
173 className: 'bkbg-apir-title bkbg-apir-clickable',
174 onClick: function () { setEditField('title'); }
175 }, a.title || 'API Endpoint');
176
177 var descEl = editField === 'description'
178 ? el('textarea', {
179 className: 'bkbg-apir-desc-input',
180 value: a.description,
181 autoFocus: true,
182 rows: 2,
183 onChange: function (e) { setAttributes({ description: e.target.value }); },
184 onBlur: function () { setEditField(null); }
185 })
186 : el('p', {
187 className: 'bkbg-apir-desc bkbg-apir-clickable',
188 onClick: function () { setEditField('description'); }
189 }, a.description || 'Click to add description…');
190
191 // Tab bar
192 var tabs = ['params', 'request', 'response'];
193 var tabLabels = { params: 'Parameters', request: 'Request', response: 'Response' };
194 var tabBar = el('div', { className: 'bkbg-apir-tabbar' },
195 tabs.map(function (t) {
196 return el('button', {
197 key: t,
198 className: 'bkbg-apir-tab' + (tab === t ? ' is-active' : ''),
199 onClick: function () { setTab(t); }
200 }, tabLabels[t]);
201 })
202 );
203
204 // Params table
205 var paramsPanel = el('div', { className: 'bkbg-apir-params', style: { display: tab === 'params' ? '' : 'none' } },
206 a.params.length === 0
207 ? el('p', { className: 'bkbg-apir-empty' }, 'No parameters. Add them in the sidebar.')
208 : el('table', { className: 'bkbg-apir-table', style: { '--bkbg-apir-table-bg': a.tableBg, '--bkbg-apir-table-alt': a.tableAltBg } },
209 el('thead', {},
210 el('tr', {},
211 el('th', {}, 'Name'),
212 el('th', {}, 'Type'),
213 el('th', {}, 'In'),
214 el('th', {}, 'Required'),
215 el('th', {}, 'Description'),
216 el('th', {}, 'Example')
217 )
218 ),
219 el('tbody', {},
220 a.params.map(function (p, i) {
221 return el('tr', { key: i, className: i % 2 ? 'alt' : '' },
222 el('td', {}, el('code', {}, p.name)),
223 el('td', {}, el('span', { className: 'bkbg-apir-type' }, p.type)),
224 el('td', {}, el('span', { className: 'bkbg-apir-loc bkbg-apir-loc-' + p.location }, p.location)),
225 el('td', {}, p.required
226 ? el('span', { className: 'bkbg-apir-req' }, '')
227 : el('span', { className: 'bkbg-apir-opt' }, '')),
228 el('td', {}, p.description),
229 el('td', {}, p.example ? el('code', {}, p.example) : '')
230 );
231 })
232 )
233 )
234 );
235
236 // Request panel
237 var requestPanel = el('div', {
238 className: 'bkbg-apir-code-panel',
239 style: { display: tab === 'request' ? '' : 'none', background: codeBg, color: codeColor }
240 },
241 a.showCopyButton && el('button', { className: 'bkbg-apir-copy' }, '📋 Copy'),
242 el('span', { className: 'bkbg-apir-lang-badge' }, a.requestLang),
243 editField === 'requestCode'
244 ? el('textarea', {
245 className: 'bkbg-apir-code-edit',
246 value: a.requestExample,
247 autoFocus: true,
248 rows: 8,
249 style: { background: codeBg, color: codeColor },
250 onChange: function (e) { setAttributes({ requestExample: e.target.value }); },
251 onBlur: function () { setEditField(null); }
252 })
253 : el('pre', {
254 className: 'bkbg-apir-code bkbg-apir-clickable',
255 style: { background: codeBg, color: codeColor },
256 onClick: function () { setEditField('requestCode'); }
257 }, a.requestExample)
258 );
259
260 // Response panel
261 var responsePanel = el('div', {
262 className: 'bkbg-apir-code-panel',
263 style: { display: tab === 'response' ? '' : 'none', background: codeBg, color: codeColor }
264 },
265 a.showCopyButton && el('button', { className: 'bkbg-apir-copy' }, '📋 Copy'),
266 el('span', { className: 'bkbg-apir-lang-badge' }, a.responseLang),
267 editField === 'responseCode'
268 ? el('textarea', {
269 className: 'bkbg-apir-code-edit',
270 value: a.responseExample,
271 autoFocus: true,
272 rows: 8,
273 style: { background: codeBg, color: codeColor },
274 onChange: function (e) { setAttributes({ responseExample: e.target.value }); },
275 onBlur: function () { setEditField(null); }
276 })
277 : el('pre', {
278 className: 'bkbg-apir-code bkbg-apir-clickable',
279 style: { background: codeBg, color: codeColor },
280 onClick: function () { setEditField('responseCode'); }
281 }, a.responseExample)
282 );
283
284 return el('div', (function () {
285 var _tv = getTypoCssVars();
286 var s = {
287 '--bkbg-apir-border': a.borderColor,
288 '--bkbg-apir-radius': a.borderRadius + 'px',
289 '--bkbg-apir-fs': a.fontSize + 'px'
290 };
291 Object.assign(s, _tv(a.textTypo || {}, '--bkbg-apir-'));
292 return { className: 'bkbg-apir-wrap', style: s };
293 })(),
294 headerEl,
295 el('div', { className: 'bkbg-apir-meta' }, titleEl, descEl),
296 tabBar,
297 el('div', { className: 'bkbg-apir-body' }, paramsPanel, requestPanel, responsePanel)
298 );
299 }
300
301 registerBlockType('blockenberg/api-reference', {
302 title: __('API Reference', 'blockenberg'),
303 icon: 'rest-api',
304 category: 'bkbg-dev',
305 description: __('Display API endpoint documentation with method badge, parameters table, and code examples.', 'blockenberg'),
306
307 edit: function (props) {
308 var a = props.attributes;
309 var setAttributes = props.setAttributes;
310
311 var tabState = useState(a.defaultTab || 'params');
312 var tab = tabState[0]; var setTab = tabState[1];
313
314 var editState = useState(null);
315 var editField = editState[0]; var setEditField = editState[1];
316
317 var methodOpts = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'].map(function (m) {
318 return { label: m, value: m };
319 });
320 var authOpts = [
321 { label: 'No Auth', value: 'none' },
322 { label: 'Bearer Token', value: 'bearer' },
323 { label: 'API Key', value: 'api-key' },
324 { label: 'Basic Auth', value: 'basic' }
325 ];
326 var themeOpts = [
327 { label: 'Dark', value: 'dark' },
328 { label: 'Light', value: 'light' }
329 ];
330 var langOpts = [
331 { label: 'cURL', value: 'curl' },
332 { label: 'JavaScript', value: 'javascript' },
333 { label: 'Python', value: 'python' },
334 { label: 'PHP', value: 'php' },
335 { label: 'Go', value: 'go' }
336 ];
337
338 function handleParamChange(idx, field, val) {
339 setAttributes({ params: updateParam(a.params, idx, field, val) });
340 }
341 function handleParamRemove(idx) {
342 setAttributes({ params: a.params.filter(function (_, i) { return i !== idx; }) });
343 }
344 function handleParamMove(from, to) {
345 var arr = a.params.slice();
346 var tmp = arr[from]; arr[from] = arr[to]; arr[to] = tmp;
347 setAttributes({ params: arr });
348 }
349 function addParam() {
350 setAttributes({ params: a.params.concat([{ name: 'param', type: 'string', required: false, location: 'query', description: '', example: '' }]) });
351 }
352
353 var inspector = el(InspectorControls, {},
354 el(PanelBody, { title: __('Endpoint Settings', 'blockenberg'), initialOpen: true },
355 el(SelectControl, {
356 label: __('HTTP Method', 'blockenberg'),
357 value: a.method,
358 options: methodOpts,
359 __nextHasNoMarginBottom: true,
360 onChange: function (v) { setAttributes({ method: v }); }
361 }),
362 el(TextControl, {
363 label: __('Base URL', 'blockenberg'),
364 value: a.baseUrl,
365 __nextHasNoMarginBottom: true,
366 onChange: function (v) { setAttributes({ baseUrl: v }); }
367 }),
368 el(TextControl, {
369 label: __('Endpoint Path', 'blockenberg'),
370 value: a.endpoint,
371 __nextHasNoMarginBottom: true,
372 onChange: function (v) { setAttributes({ endpoint: v }); }
373 }),
374 el(SelectControl, {
375 label: __('Authentication Type', 'blockenberg'),
376 value: a.authType,
377 options: authOpts,
378 __nextHasNoMarginBottom: true,
379 onChange: function (v) { setAttributes({ authType: v }); }
380 }),
381 el(ToggleControl, {
382 label: __('Show Base URL', 'blockenberg'),
383 checked: a.showBaseUrl,
384 __nextHasNoMarginBottom: true,
385 onChange: function (v) { setAttributes({ showBaseUrl: v }); }
386 }),
387 el(ToggleControl, {
388 label: __('Show Auth Badge', 'blockenberg'),
389 checked: a.showAuth,
390 __nextHasNoMarginBottom: true,
391 onChange: function (v) { setAttributes({ showAuth: v }); }
392 }),
393 el(ToggleControl, {
394 label: __('Show Copy Button', 'blockenberg'),
395 checked: a.showCopyButton,
396 __nextHasNoMarginBottom: true,
397 onChange: function (v) { setAttributes({ showCopyButton: v }); }
398 })
399 ),
400 el(PanelBody, { title: __('Code Examples', 'blockenberg'), initialOpen: false },
401 el(SelectControl, {
402 label: __('Request Language', 'blockenberg'),
403 value: a.requestLang,
404 options: langOpts,
405 __nextHasNoMarginBottom: true,
406 onChange: function (v) { setAttributes({ requestLang: v }); }
407 }),
408 el(SelectControl, {
409 label: __('Code Theme', 'blockenberg'),
410 value: a.codeTheme,
411 options: themeOpts,
412 __nextHasNoMarginBottom: true,
413 onChange: function (v) { setAttributes({ codeTheme: v }); }
414 })
415 ),
416 el(PanelBody, { title: __('Parameters (' + a.params.length + ')', 'blockenberg'), initialOpen: false },
417 a.params.map(function (p, i) {
418 return el(ParamEditor, {
419 key: i,
420 param: p,
421 idx: i,
422 total: a.params.length,
423 onChange: handleParamChange,
424 onRemove: function () { handleParamRemove(i); },
425 onMove: handleParamMove
426 });
427 }),
428 el(Button, {
429 variant: 'secondary',
430 style: { marginTop: '8px', width: '100%' },
431 onClick: addParam
432 }, __('+ Add Parameter', 'blockenberg'))
433 ),
434 el(PanelBody, { title: __('Style', 'blockenberg'), initialOpen: false },
435 el(RangeControl, {
436 label: __('Border Radius', 'blockenberg'),
437 value: a.borderRadius,
438 min: 0, max: 20,
439 __nextHasNoMarginBottom: true,
440 onChange: function (v) { setAttributes({ borderRadius: v }); }
441 }),
442 ),
443
444 el( PanelBody, { title: __( 'Typography', 'blockenberg' ), initialOpen: false },
445 el(getTypographyControl(), { label: __('Text Typography', 'blockenberg'), value: a.textTypo || {}, onChange: function (v) { setAttributes({ textTypo: v }); } })
446 ),
447 el(PanelColorSettings, {
448 title: __('Header Colors', 'blockenberg'),
449 initialOpen: false,
450 colorSettings: [
451 { value: a.headerBg, onChange: function (c) { setAttributes({ headerBg: c || '#1e1e2e' }); }, label: __('Header Background', 'blockenberg') },
452 { value: a.headerColor, onChange: function (c) { setAttributes({ headerColor: c || '#e2e8f0' }); }, label: __('Header Text', 'blockenberg') },
453 { value: a.borderColor, onChange: function (c) { setAttributes({ borderColor: c || '#e2e8f0' }); }, label: __('Border', 'blockenberg') },
454 { value: a.tableBg, onChange: function (c) { setAttributes({ tableBg: c || '#ffffff' }); }, label: __('Table Background', 'blockenberg') },
455 { value: a.tableAltBg, onChange: function (c) { setAttributes({ tableAltBg: c || '#f8fafc' }); }, label: __('Table Alt Row', 'blockenberg') }
456 ]
457 }),
458 el(PanelColorSettings, {
459 title: __('Method Colors', 'blockenberg'),
460 initialOpen: false,
461 colorSettings: [
462 { value: a.getBg, onChange: function (c) { setAttributes({ getBg: c || '#22c55e' }); }, label: 'GET' },
463 { value: a.postBg, onChange: function (c) { setAttributes({ postBg: c || '#3b82f6' }); }, label: 'POST' },
464 { value: a.putBg, onChange: function (c) { setAttributes({ putBg: c || '#f59e0b' }); }, label: 'PUT' },
465 { value: a.patchBg, onChange: function (c) { setAttributes({ patchBg: c || '#8b5cf6' }); }, label: 'PATCH' },
466 { value: a.deleteBg, onChange: function (c) { setAttributes({ deleteBg: c || '#ef4444' }); }, label: 'DELETE' }
467 ]
468 })
469 );
470
471 var blockProps = useBlockProps({ className: 'bkbg-editor-wrap', 'data-block-label': 'API Reference' });
472
473 return el('div', blockProps,
474 inspector,
475 el(ApiPreview, {
476 a: a,
477 setAttributes: setAttributes,
478 tab: tab,
479 setTab: setTab,
480 editField: editField,
481 setEditField: setEditField
482 })
483 );
484 },
485
486 save: function (props) {
487 return el('div', useBlockProps.save(),
488 el('div', { className: 'bkbg-apir-app', 'data-opts': JSON.stringify(props.attributes) })
489 );
490 }
491 });
492 }() );
493