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 / link-roundup / index.js

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

217 lines 16.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 __ = 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, _tv;
18 function getTypoControl() { return _tc || (_tc = window.bkbgTypographyControl); }
19 function getTypoCssVars() { return _tv || (_tv = window.bkbgTypoCssVars); }
20 var IP = function () { return window.bkbgIconPicker; };
21
22 var DATE_LABELS = [
23 { label: 'Week of', value: 'Week of' },
24 { label: 'Monthly Roundup', value: 'Monthly Roundup' },
25 { label: "This Week's Reads", value: "This Week's Reads" },
26 { label: 'Issue #', value: 'Issue #' },
27 { label: 'Edition:', value: 'Edition:' }
28 ];
29
30 function updateLink(links, idx, key, val) {
31 return links.map(function (l, i) {
32 if (i !== idx) return l;
33 var c = Object.assign({}, l); c[key] = val; return c;
34 });
35 }
36
37 registerBlockType('blockenberg/link-roundup', {
38 edit: function (props) {
39 var attr = props.attributes;
40 var set = props.setAttributes;
41 var links = attr.links || [];
42
43 var blockProps = useBlockProps((function () {
44 var _tvFn = getTypoCssVars();
45 var s = { padding: attr.paddingTop + 'px 0 ' + attr.paddingBottom + 'px', background: attr.bgColor, borderRadius: attr.borderRadius + 'px' };
46 if (_tvFn) {
47 Object.assign(s, _tvFn(attr.titleTypo, '--bkbg-lru-tt-'));
48 Object.assign(s, _tvFn(attr.subtitleTypo, '--bkbg-lru-st-'));
49 Object.assign(s, _tvFn(attr.itemTypo, '--bkbg-lru-it-'));
50 }
51 return { style: s };
52 })());
53
54 var controls = el(InspectorControls, {},
55 el(PanelBody, { title: __('Header', 'blockenberg'), initialOpen: true },
56 el(TextControl, { label: __('Date Label', 'blockenberg'), value: attr.dateLabel, __nextHasNoMarginBottom: true, onChange: function (v) { set({ dateLabel: v }); } }),
57 el('div', { style: { marginTop: '8px' } },
58 el(ToggleControl, { label: __('Show Date', 'blockenberg'), checked: attr.showDate, __nextHasNoMarginBottom: true, onChange: function (v) { set({ showDate: v }); } })
59 ),
60 attr.showDate && el('div', { style: { marginTop: '8px' } },
61 el(TextControl, { label: __('Publish Date', 'blockenberg'), value: attr.publishDate, placeholder: 'e.g. February 24, 2026', __nextHasNoMarginBottom: true, onChange: function (v) { set({ publishDate: v }); } })
62 ),
63 el('div', { style: { marginTop: '8px' } },
64 el(ToggleControl, { label: __('Show Subtitle', 'blockenberg'), checked: attr.showSubtitle, __nextHasNoMarginBottom: true, onChange: function (v) { set({ showSubtitle: v }); } })
65 )
66 ),
67 el(PanelBody, { title: __('Display', 'blockenberg'), initialOpen: true },
68 el(SelectControl, {
69 label: __('Style', 'blockenberg'), value: attr.style, __nextHasNoMarginBottom: true,
70 options: [{ label: 'Cards', value: 'cards' }, { label: 'List', value: 'list' }, { label: 'Magazine (large)', value: 'magazine' }],
71 onChange: function (v) { set({ style: v }); }
72 }),
73 el('div', { style: { marginTop: '8px' } },
74 el(ToggleControl, { label: __('Group by Category', 'blockenberg'), checked: attr.groupByCategory, __nextHasNoMarginBottom: true, onChange: function (v) { set({ groupByCategory: v }); } })
75 ),
76 el('div', { style: { marginTop: '8px' } },
77 el(ToggleControl, { label: __('Show Emoji', 'blockenberg'), checked: attr.showEmoji, __nextHasNoMarginBottom: true, onChange: function (v) { set({ showEmoji: v }); } })
78 ),
79 el('div', { style: { marginTop: '8px' } },
80 el(ToggleControl, { label: __('Show Source', 'blockenberg'), checked: attr.showSource, __nextHasNoMarginBottom: true, onChange: function (v) { set({ showSource: v }); } })
81 ),
82 el('div', { style: { marginTop: '8px' } },
83 el(ToggleControl, { label: __('Show Excerpt', 'blockenberg'), checked: attr.showExcerpt, __nextHasNoMarginBottom: true, onChange: function (v) { set({ showExcerpt: v }); } })
84 ),
85 el('div', { style: { marginTop: '8px' } },
86 el(ToggleControl, { label: __('Show Category Tag', 'blockenberg'), checked: attr.showCategory, __nextHasNoMarginBottom: true, onChange: function (v) { set({ showCategory: v }); } })
87 ),
88 el('div', { style: { marginTop: '8px' } },
89 el(ToggleControl, { label: __('Open Links in New Tab', 'blockenberg'), checked: attr.openInNewTab, __nextHasNoMarginBottom: true, onChange: function (v) { set({ openInNewTab: v }); } })
90 )
91 ),
92 el(PanelBody, { title: __('Spacing', 'blockenberg'), initialOpen: false },
93 el(RangeControl, { label: __('Border Radius', 'blockenberg'), value: attr.borderRadius, min: 0, max: 30, __nextHasNoMarginBottom: true, onChange: function (v) { set({ borderRadius: v }); } }),
94 el('div', { style: { marginTop: '12px' } },
95 el(RangeControl, { label: __('Card Radius', 'blockenberg'), value: attr.cardRadius, min: 0, max: 20, __nextHasNoMarginBottom: true, onChange: function (v) { set({ cardRadius: v }); } })
96 ),
97 el('div', { style: { marginTop: '12px' } },
98 el(RangeControl, { label: __('Padding Top', 'blockenberg'), value: attr.paddingTop, min: 0, max: 100, __nextHasNoMarginBottom: true, onChange: function (v) { set({ paddingTop: v }); } })
99 ),
100 el('div', { style: { marginTop: '12px' } },
101 el(RangeControl, { label: __('Padding Bottom', 'blockenberg'), value: attr.paddingBottom, min: 0, max: 100, __nextHasNoMarginBottom: true, onChange: function (v) { set({ paddingBottom: v }); } })
102 )
103 ),
104 el(PanelColorSettings, {
105 title: __('Colors', 'blockenberg'), initialOpen: false,
106 colorSettings: [
107 { label: __('Background', 'blockenberg'), value: attr.bgColor, onChange: function (v) { set({ bgColor: v || '#f8fafc' }); } },
108 { label: __('Border', 'blockenberg'), value: attr.borderColor, onChange: function (v) { set({ borderColor: v || '#e2e8f0' }); } },
109 { label: __('Heading', 'blockenberg'), value: attr.headingColor, onChange: function (v) { set({ headingColor: v || '#0f172a' }); } },
110 { label: __('Subtitle', 'blockenberg'), value: attr.subtitleColor, onChange: function (v) { set({ subtitleColor: v || '#64748b' }); } },
111 { label: __('Date', 'blockenberg'), value: attr.dateColor, onChange: function (v) { set({ dateColor: v || '#94a3b8' }); } },
112 { label: __('Card Background', 'blockenberg'), value: attr.cardBg, onChange: function (v) { set({ cardBg: v || '#ffffff' }); } },
113 { label: __('Card Border', 'blockenberg'), value: attr.cardBorder, onChange: function (v) { set({ cardBorder: v || '#e2e8f0' }); } },
114 { label: __('Link Color', 'blockenberg'), value: attr.linkColor, onChange: function (v) { set({ linkColor: v || '#2563eb' }); } },
115 { label: __('Source', 'blockenberg'), value: attr.sourceColor, onChange: function (v) { set({ sourceColor: v || '#94a3b8' }); } },
116 { label: __('Excerpt', 'blockenberg'), value: attr.excerptColor, onChange: function (v) { set({ excerptColor: v || '#475569' }); } },
117 { label: __('Category Tag BG', 'blockenberg'), value: attr.catBg, onChange: function (v) { set({ catBg: v || '#e0f2fe' }); } },
118 { label: __('Category Tag Text', 'blockenberg'), value: attr.catColor, onChange: function (v) { set({ catColor: v || '#0369a1' }); } },
119 { label: __('Accent', 'blockenberg'), value: attr.accentColor, onChange: function (v) { set({ accentColor: v || '#2563eb' }); } }
120 ]
121 }),
122 el(PanelBody, { title: 'Typography', initialOpen: false },
123 getTypoControl() && el(getTypoControl(), { label: __('Title'), value: attr.titleTypo || {}, onChange: function (v) { set({ titleTypo: v }); } }),
124 getTypoControl() && el(getTypoControl(), { label: __('Subtitle'), value: attr.subtitleTypo || {}, onChange: function (v) { set({ subtitleTypo: v }); } }),
125 getTypoControl() && el(getTypoControl(), { label: __('Item Title'), value: attr.itemTypo || {}, onChange: function (v) { set({ itemTypo: v }); } })
126 ),
127
128 );
129
130 var isCards = attr.style === 'cards';
131 var isMag = attr.style === 'magazine';
132 var gridStyle = isCards
133 ? { display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(280px, 1fr))', gap: '14px' }
134 : isMag
135 ? { display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(340px, 1fr))', gap: '18px' }
136 : { display: 'flex', flexDirection: 'column', gap: '8px' };
137
138 var linkCards = el('div', { style: gridStyle },
139 links.map(function (lnk, idx) {
140 var isListStyle = attr.style === 'list';
141 var cardStyle = {
142 background: attr.cardBg,
143 border: '1px solid ' + attr.cardBorder,
144 borderRadius: attr.cardRadius + 'px',
145 padding: isListStyle ? '10px 14px' : '14px 16px',
146 display: isListStyle ? 'flex' : 'block',
147 alignItems: isListStyle ? 'flex-start' : undefined,
148 gap: isListStyle ? '10px' : undefined
149 };
150 if (attr.style === 'magazine') {
151 cardStyle.borderLeft = '4px solid ' + attr.accentColor;
152 }
153
154 var emojiEl = attr.showEmoji && (function () {
155 var _et = lnk.emojiType || 'custom-char';
156 var _style = { fontSize: isListStyle ? '16px' : '20px', flexShrink: isListStyle ? '0' : undefined, display: isListStyle ? 'inline-flex' : 'inline-flex', alignItems: 'center', justifyContent: 'center', marginRight: isListStyle ? '0' : '6px', marginBottom: isListStyle ? '0' : '6px' };
157 if (_et !== 'custom-char' && IP()) {
158 var _node = IP().buildEditorIcon(_et, lnk.emoji, lnk.emojiDashicon, lnk.emojiImageUrl, lnk.emojiDashiconColor);
159 if (_node) return el('span', { style: _style }, _node);
160 }
161 return el('span', { style: _style }, lnk.emoji || '🔗');
162 })();
163
164 return el('div', { key: idx, style: cardStyle },
165 emojiEl,
166 el('div', { style: { flex: 1, minWidth: 0 } },
167 el('div', { style: { display: 'flex', alignItems: 'center', gap: '8px', flexWrap: 'wrap', marginBottom: '4px' } },
168 el(TextControl, { value: lnk.title, label: '', placeholder: __('Link Title', 'blockenberg'), __nextHasNoMarginBottom: true, style: { fontWeight: 600, fontSize: '14px', color: attr.linkColor, flex: '1' }, onChange: function (v) { set({ links: updateLink(links, idx, 'title', v) }); } }),
169 attr.showCategory && el(TextControl, { value: lnk.category, label: '', placeholder: __('Category', 'blockenberg'), __nextHasNoMarginBottom: true, style: { width: '100px', fontSize: '11px' }, onChange: function (v) { set({ links: updateLink(links, idx, 'category', v) }); } })
170 ),
171 el('div', { style: { display: 'flex', gap: '8px', flexWrap: 'wrap', alignItems: 'center', marginBottom: '4px' } },
172 el(TextControl, { value: lnk.url, label: '', placeholder: __('https://…', 'blockenberg'), __nextHasNoMarginBottom: true, style: { flex: '1', fontSize: '12px' }, onChange: function (v) { set({ links: updateLink(links, idx, 'url', v) }); } }),
173 attr.showEmoji && el(IP().IconPickerControl, {
174 iconType: lnk.emojiType || 'custom-char',
175 customChar: lnk.emoji || '',
176 dashicon: lnk.emojiDashicon || '',
177 imageUrl: lnk.emojiImageUrl || '',
178 onChangeType: function (v) { set({ links: updateLink(links, idx, 'emojiType', v) }); },
179 onChangeChar: function (v) { set({ links: updateLink(links, idx, 'emoji', v) }); },
180 onChangeDashicon: function (v) { set({ links: updateLink(links, idx, 'emojiDashicon', v) }); },
181 onChangeImageUrl: function (v) { set({ links: updateLink(links, idx, 'emojiImageUrl', v) }); },
182 label: ''
183 }),
184 attr.showSource && el(TextControl, { value: lnk.source, label: '', placeholder: __('Source', 'blockenberg'), __nextHasNoMarginBottom: true, style: { width: '120px', fontSize: '12px' }, onChange: function (v) { set({ links: updateLink(links, idx, 'source', v) }); } })
185 ),
186 attr.showExcerpt && el(TextareaControl, { value: lnk.excerpt, label: '', placeholder: __('Brief excerpt or summary…', 'blockenberg'), rows: 2, __nextHasNoMarginBottom: true, onChange: function (v) { set({ links: updateLink(links, idx, 'excerpt', v) }); } }),
187 el(Button, { variant: 'link', isDestructive: true, style: { fontSize: '11px', marginTop: '4px' }, onClick: function () { set({ links: links.filter(function (_, i) { return i !== idx; }) }); } }, __('Remove', 'blockenberg'))
188 )
189 );
190 })
191 );
192
193 return el('div', blockProps,
194 controls,
195 el('div', { style: { padding: '24px' } },
196 el('div', { style: { marginBottom: '20px' } },
197 attr.showDate && attr.publishDate && el('div', { style: { fontSize: '12px', color: attr.dateColor, marginBottom: '4px', fontWeight: 500 } }, attr.dateLabel + ' ' + attr.publishDate),
198 el(RichText, { tagName: 'h2', className: 'bkbg-lru-title', value: attr.title, allowedFormats: ['core/bold', 'core/italic'], placeholder: __('Roundup Title', 'blockenberg'), style: { margin: '0 0 4px', color: attr.headingColor }, onChange: function (v) { set({ title: v }); } }),
199 attr.showSubtitle && el(RichText, { tagName: 'p', className: 'bkbg-lru-subtitle', value: attr.subtitle, allowedFormats: ['core/bold', 'core/italic'], placeholder: __('Optional subtitle or intro…', 'blockenberg'), style: { margin: '0 0 16px', color: attr.subtitleColor }, onChange: function (v) { set({ subtitle: v }); } })
200 ),
201 linkCards,
202 el('div', { style: { textAlign: 'center', marginTop: '14px' } },
203 el(Button, { variant: 'secondary', onClick: function () { set({ links: links.concat([{ title: '', url: '', source: '', excerpt: '', category: 'General', emoji: '🔗', emojiType: 'custom-char', emojiDashicon: '', emojiImageUrl: '' }]) }); } }, __('+ Add Link', 'blockenberg'))
204 )
205 )
206 );
207 },
208 save: function (props) {
209 var attr = props.attributes;
210 var useBlockProps = wp.blockEditor.useBlockProps;
211 return el('div', useBlockProps.save(),
212 el('div', { className: 'bkbg-lru-app', 'data-opts': JSON.stringify(attr) })
213 );
214 }
215 });
216 }() );
217