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 / definition-block / index.js

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

249 lines 18.4 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 _dfnTC, _dfnTV;
17 function _tc() { return _dfnTC || (_dfnTC = window.bkbgTypographyControl); }
18 function _tv(typo, prefix) { return (_dfnTV || (_dfnTV = window.bkbgTypoCssVars))(typo, prefix); }
19
20 var POS_OPTIONS = [
21 { value: 'noun', label: 'noun' },
22 { value: 'verb', label: 'verb' },
23 { value: 'adjective', label: 'adjective' },
24 { value: 'adverb', label: 'adverb' },
25 { value: 'pronoun', label: 'pronoun' },
26 { value: 'preposition',label: 'preposition' },
27 { value: 'conjunction',label: 'conjunction' },
28 { value: 'interjection',label:'interjection' },
29 { value: 'phrase', label: 'phrase' },
30 { value: 'abbreviation',label:'abbreviation' },
31 { value: 'idiom', label: 'idiom' }
32 ];
33
34 var STYLE_OPTIONS = [
35 { value: 'card', label: 'Card (bordered)' },
36 { value: 'classic', label: 'Classic (left accent)' },
37 { value: 'minimal', label: 'Minimal (no border)' },
38 { value: 'spotlight',label: 'Spotlight (accent header)' }
39 ];
40
41 registerBlockType('blockenberg/definition-block', {
42 edit: function (props) {
43 var attr = props.attributes;
44 var set = props.setAttributes;
45 var examples = attr.examples || [''];
46
47 var blockProps = useBlockProps({ style: Object.assign({ paddingTop: attr.paddingTop + 'px', paddingBottom: attr.paddingBottom + 'px', '--bkbg-dfn-trm-fs': (attr.termFontSize || 24) + 'px', '--bkbg-dfn-sd-fs': (attr.shortDefFontSize || 16) + 'px', '--bkbg-dfn-ld-fs': (attr.longDefFontSize || 14) + 'px' }, _tv(attr.typoTerm || {}, '--bkbg-dfn-trm-'), _tv(attr.typoShortDef || {}, '--bkbg-dfn-sd-'), _tv(attr.typoLongDef || {}, '--bkbg-dfn-ld-')) });
48
49 function updateExample(idx, val) {
50 set({ examples: examples.map(function (e, i) { return i === idx ? val : e; }) });
51 }
52
53 /* card style */
54 var wrapStyle = {
55 background: attr.bgColor,
56 borderRadius: attr.borderRadius + 'px',
57 overflow: 'hidden'
58 };
59 if (attr.style === 'card') {
60 wrapStyle.border = '1px solid ' + attr.borderColor;
61 wrapStyle.padding = '20px 22px';
62 } else if (attr.style === 'classic') {
63 wrapStyle.borderLeft = '5px solid ' + attr.accentColor;
64 wrapStyle.padding = '16px 20px';
65 } else if (attr.style === 'minimal') {
66 wrapStyle.padding = '8px 0';
67 } else if (attr.style === 'spotlight') {
68 wrapStyle.border = '1px solid ' + attr.borderColor;
69 }
70
71 var headerBg = attr.style === 'spotlight'
72 ? { background: attr.accentColor, padding: '14px 22px' }
73 : null;
74
75 var bodyPadding = attr.style === 'spotlight' ? { padding: '16px 22px' } : {};
76
77 var termRow = el('div', { style: headerBg || { marginBottom: '8px' } },
78 el('div', { style: { display: 'flex', alignItems: 'baseline', gap: '10px', flexWrap: 'wrap' } },
79 el(RichText, {
80 tagName: 'span', value: attr.term, allowedFormats: [],
81 className: 'bkbg-dfn-term',
82 placeholder: __('Term', 'blockenberg'),
83 style: { color: attr.style === 'spotlight' ? '#fff' : attr.termColor },
84 onChange: function (v) { set({ term: v }); }
85 }),
86 attr.showPronunciation && el(TextControl, {
87 value: attr.pronunciation, label: '', placeholder: '/prəˌnʌnsiˈeɪʃən/',
88 __nextHasNoMarginBottom: true,
89 style: { fontSize: '14px', color: attr.style === 'spotlight' ? 'rgba(255,255,255,0.8)' : attr.pronunciationColor, fontStyle: 'italic', fontFamily: 'serif', width: '200px' },
90 onChange: function (v) { set({ pronunciation: v }); }
91 }),
92 attr.showPartOfSpeech && el('span', { style: { background: attr.style === 'spotlight' ? 'rgba(255,255,255,0.2)' : attr.posBg, color: attr.style === 'spotlight' ? '#fff' : attr.posColor, padding: '2px 9px', borderRadius: '999px', fontSize: '12px', fontStyle: 'italic', fontWeight: 600 } }, attr.partOfSpeech)
93 )
94 );
95
96 var controls = el(InspectorControls, {},
97 el(PanelBody, { title: __('Definition', 'blockenberg'), initialOpen: true },
98 el(SelectControl, {
99 label: __('Part of Speech', 'blockenberg'), value: attr.partOfSpeech, __nextHasNoMarginBottom: true,
100 options: POS_OPTIONS,
101 onChange: function (v) { set({ partOfSpeech: v }); }
102 }),
103 el('div', { style: { marginTop: '8px' } },
104 el(ToggleControl, { label: __('Show Pronunciation', 'blockenberg'), checked: attr.showPronunciation, __nextHasNoMarginBottom: true, onChange: function (v) { set({ showPronunciation: v }); } })
105 ),
106 el('div', { style: { marginTop: '8px' } },
107 el(ToggleControl, { label: __('Show Part of Speech', 'blockenberg'), checked: attr.showPartOfSpeech, __nextHasNoMarginBottom: true, onChange: function (v) { set({ showPartOfSpeech: v }); } })
108 ),
109 el('div', { style: { marginTop: '8px' } },
110 el(ToggleControl, { label: __('Show Full Explanation', 'blockenberg'), checked: attr.showLongDef, __nextHasNoMarginBottom: true, onChange: function (v) { set({ showLongDef: v }); } })
111 ),
112 el('div', { style: { marginTop: '8px' } },
113 el(ToggleControl, { label: __('Show Examples', 'blockenberg'), checked: attr.showExamples, __nextHasNoMarginBottom: true, onChange: function (v) { set({ showExamples: v }); } })
114 ),
115 el('div', { style: { marginTop: '8px' } },
116 el(ToggleControl, { label: __('Show Synonyms', 'blockenberg'), checked: attr.showSynonyms, __nextHasNoMarginBottom: true, onChange: function (v) { set({ showSynonyms: v }); } })
117 ),
118 el('div', { style: { marginTop: '8px' } },
119 el(ToggleControl, { label: __('Show Antonyms', 'blockenberg'), checked: attr.showAntonyms, __nextHasNoMarginBottom: true, onChange: function (v) { set({ showAntonyms: v }); } })
120 ),
121 el('div', { style: { marginTop: '8px' } },
122 el(ToggleControl, { label: __('Show Etymology', 'blockenberg'), checked: attr.showEtymology, __nextHasNoMarginBottom: true, onChange: function (v) { set({ showEtymology: v }); } })
123 )
124 ),
125 el(PanelBody, { title: __('Source', 'blockenberg'), initialOpen: false },
126 el(TextControl, { label: __('Source Label', 'blockenberg'), value: attr.sourceLabel, placeholder: 'Merriam-Webster', __nextHasNoMarginBottom: true, onChange: function (v) { set({ sourceLabel: v }); } }),
127 el('div', { style: { marginTop: '8px' } },
128 el(TextControl, { label: __('Source URL', 'blockenberg'), value: attr.sourceUrl, placeholder: 'https://…', __nextHasNoMarginBottom: true, onChange: function (v) { set({ sourceUrl: v }); } })
129 )
130 ),
131 el(PanelBody, { title: __('Style & Spacing', 'blockenberg'), initialOpen: false },
132 el(SelectControl, {
133 label: __('Card Style', 'blockenberg'), value: attr.style, __nextHasNoMarginBottom: true,
134 options: STYLE_OPTIONS,
135 onChange: function (v) { set({ style: v }); }
136 }),
137 el('div', { style: { marginTop: '10px' } },
138 el(RangeControl, { label: __('Border Radius', 'blockenberg'), value: attr.borderRadius, min: 0, max: 30, __nextHasNoMarginBottom: true, onChange: function (v) { set({ borderRadius: v }); } })
139 ),
140 el('div', { style: { marginTop: '10px' } },
141 el(RangeControl, { label: __('Padding Top', 'blockenberg'), value: attr.paddingTop, min: 0, max: 100, __nextHasNoMarginBottom: true, onChange: function (v) { set({ paddingTop: v }); } })
142 ),
143 el('div', { style: { marginTop: '10px' } },
144 el(RangeControl, { label: __('Padding Bottom', 'blockenberg'), value: attr.paddingBottom, min: 0, max: 100, __nextHasNoMarginBottom: true, onChange: function (v) { set({ paddingBottom: v }); } })
145 )
146 ),
147 el(PanelColorSettings, {
148 title: __('Colors', 'blockenberg'), initialOpen: false,
149 colorSettings: [
150 { label: __('Background', 'blockenberg'), value: attr.bgColor, onChange: function (v) { set({ bgColor: v || '#ffffff' }); } },
151 { label: __('Border', 'blockenberg'), value: attr.borderColor, onChange: function (v) { set({ borderColor: v || '#e2e8f0' }); } },
152 { label: __('Accent', 'blockenberg'), value: attr.accentColor, onChange: function (v) { set({ accentColor: v || '#7c3aed' }); } },
153 { label: __('Term', 'blockenberg'), value: attr.termColor, onChange: function (v) { set({ termColor: v || '#0f172a' }); } },
154 { label: __('Pronunciation', 'blockenberg'), value: attr.pronunciationColor, onChange: function (v) { set({ pronunciationColor: v || '#7c3aed' }); } },
155 { label: __('Part of Speech BG', 'blockenberg'), value: attr.posBg, onChange: function (v) { set({ posBg: v || '#f5f3ff' }); } },
156 { label: __('Part of Speech Text', 'blockenberg'), value: attr.posColor, onChange: function (v) { set({ posColor: v || '#7c3aed' }); } },
157 { label: __('Short Definition', 'blockenberg'), value: attr.shortDefColor, onChange: function (v) { set({ shortDefColor: v || '#1e293b' }); } },
158 { label: __('Long Explanation', 'blockenberg'), value: attr.longDefColor, onChange: function (v) { set({ longDefColor: v || '#475569' }); } },
159 { label: __('Examples', 'blockenberg'), value: attr.exampleColor, onChange: function (v) { set({ exampleColor: v || '#475569' }); } },
160 { label: __('Section Labels', 'blockenberg'), value: attr.labelColor, onChange: function (v) { set({ labelColor: v || '#94a3b8' }); } },
161 { label: __('Synonym / Antonym Tags', 'blockenberg'), value: attr.synonymColor, onChange: function (v) { set({ synonymColor: v || '#7c3aed' }); } }
162 ]
163 }),
164 el(PanelBody, { title: __('Typography', 'blockenberg'), initialOpen: false },
165 _tc() && el(_tc(), { label: __('Term'), typo: attr.typoTerm || {}, onChange: function (v) { set({ typoTerm: v }); }, defaultSize: attr.termFontSize || 24 }),
166 _tc() && el(_tc(), { label: __('Short definition'), typo: attr.typoShortDef || {}, onChange: function (v) { set({ typoShortDef: v }); }, defaultSize: attr.shortDefFontSize || 16 }),
167 _tc() && el(_tc(), { label: __('Long explanation'), typo: attr.typoLongDef || {}, onChange: function (v) { set({ typoLongDef: v }); }, defaultSize: attr.longDefFontSize || 14 }),
168 el(RangeControl, { label: __('Examples font size (px)', 'blockenberg'), value: attr.exampleFontSize, min: 10, max: 20, onChange: function (v) { set({ exampleFontSize: v }); }, __nextHasNoMarginBottom: true }),
169 el(RangeControl, { label: __('Etymology font size (px)', 'blockenberg'), value: attr.etymologyFontSize, min: 10, max: 20, onChange: function (v) { set({ etymologyFontSize: v }); }, __nextHasNoMarginBottom: true }),
170 el(RangeControl, { label: __('Tags font size (px)', 'blockenberg'), value: attr.tagFontSize, min: 10, max: 18, onChange: function (v) { set({ tagFontSize: v }); }, __nextHasNoMarginBottom: true })
171 )
172 );
173
174 function sectionLabel(text) {
175 return el('div', { style: { fontSize: '10px', fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.07em', color: attr.labelColor, marginBottom: '5px', marginTop: '14px' } }, text);
176 }
177
178 function tagList(commaSeparated, color, fontSize) {
179 return commaSeparated.split(',').map(function (s, i) {
180 var t = s.trim();
181 if (!t) return null;
182 return el('span', { key: i, style: { background: color + '18', color: color, padding: '2px 8px', borderRadius: '999px', fontSize: (fontSize || 12) + 'px', fontWeight: 500, marginRight: '5px', marginBottom: '4px', display: 'inline-block' } }, t) });
183 }
184
185 var body = el('div', { style: bodyPadding },
186 sectionLabel(__('Short Definition', 'blockenberg')),
187 el(RichText, { tagName: 'p', value: attr.shortDef, allowedFormats: ['core/bold', 'core/italic'], className: 'bkbg-dfn-short-def', placeholder: __('One-sentence definition…', 'blockenberg'), style: { margin: '0 0 4px', color: attr.shortDefColor }, onChange: function (v) { set({ shortDef: v }); } }),
188
189 attr.showLongDef && el('div', {},
190 sectionLabel(__('Explanation', 'blockenberg')),
191 el(RichText, { tagName: 'p', value: attr.longDef, allowedFormats: ['core/bold', 'core/italic', 'core/link'], className: 'bkbg-dfn-long-def', placeholder: __('Detailed explanation…', 'blockenberg'), style: { margin: 0, color: attr.longDefColor }, onChange: function (v) { set({ longDef: v }); } })
192 ),
193
194 attr.showExamples && el('div', {},
195 sectionLabel(__('Examples', 'blockenberg')),
196 examples.map(function (ex, idx) {
197 return el('div', { key: idx, style: { display: 'flex', alignItems: 'center', gap: '6px', marginBottom: '4px' } },
198 el('span', { style: { color: attr.accentColor, fontStyle: 'italic', flexShrink: 0, lineHeight: 1 } }, '"'),
199 el(TextControl, { value: ex, label: '', placeholder: __('Example sentence…', 'blockenberg'), __nextHasNoMarginBottom: true, style: { flex: 1, fontSize: (attr.exampleFontSize || 13) + 'px', fontStyle: 'italic', color: attr.exampleColor }, onChange: function (v) { updateExample(idx, v); } }),
200 el(Button, { isSmall: true, isDestructive: true, variant: 'tertiary', onClick: function () { set({ examples: examples.filter(function (_, i) { return i !== idx; }) }); } }, '×')
201 ) }),
202 el(Button, { variant: 'link', style: { fontSize: '11px', marginTop: '2px' }, onClick: function () { set({ examples: examples.concat(['']) }); } }, '+ Add Example')
203 ),
204
205 attr.showSynonyms && el('div', {},
206 sectionLabel(__('Synonyms', 'blockenberg')),
207 el('div', { style: { display: 'flex', alignItems: 'center', gap: '8px', flexWrap: 'wrap' } },
208 el(TextControl, { value: attr.synonyms, label: '', placeholder: __('word1, word2, word3', 'blockenberg'), __nextHasNoMarginBottom: true, style: { flex: 1, fontSize: '13px' }, onChange: function (v) { set({ synonyms: v }); } })
209 ),
210 attr.synonyms && el('div', { style: { marginTop: '5px', display: 'flex', flexWrap: 'wrap' } }, tagList(attr.synonyms, attr.synonymColor, attr.tagFontSize || 12))
211 ),
212
213 attr.showAntonyms && el('div', {},
214 sectionLabel(__('Antonyms', 'blockenberg')),
215 el(TextControl, { value: attr.antonyms, label: '', placeholder: __('word1, word2', 'blockenberg'), __nextHasNoMarginBottom: true, style: { flex: 1, fontSize: '13px' }, onChange: function (v) { set({ antonyms: v }); } }),
216 attr.antonyms && el('div', { style: { marginTop: '5px', display: 'flex', flexWrap: 'wrap' } }, tagList(attr.antonyms, '#dc2626', attr.tagFontSize || 12))
217 ),
218
219 attr.showEtymology && el('div', {},
220 sectionLabel(__('Etymology', 'blockenberg')),
221 el(RichText, { tagName: 'p', value: attr.etymology, allowedFormats: ['core/bold', 'core/italic'], placeholder: __('Word origin and history…', 'blockenberg'), style: { margin: 0, fontSize: (attr.etymologyFontSize || 13) + 'px', color: attr.longDefColor, fontStyle: 'italic', lineHeight: 1.6 }, onChange: function (v) { set({ etymology: v }); } })
222 ),
223
224 (attr.sourceLabel || attr.sourceUrl) && el('div', { style: { marginTop: '14px', paddingTop: '10px', borderTop: '1px solid ' + attr.borderColor, fontSize: '11px', color: attr.labelColor } },
225 '— Source: ',
226 attr.sourceUrl
227 ? el('a', { href: attr.sourceUrl, target: '_blank', rel: 'noopener', style: { color: attr.accentColor } }, attr.sourceLabel || attr.sourceUrl)
228 : el('span', {}, attr.sourceLabel)
229 )
230 );
231
232 return el('div', blockProps,
233 controls,
234 el('div', { style: wrapStyle },
235 termRow,
236 body
237 )
238 );
239 },
240 save: function (props) {
241 var attr = props.attributes;
242 var useBlockProps = wp.blockEditor.useBlockProps;
243 return el('div', useBlockProps.save(),
244 el('div', { className: 'bkbg-dfn-app', 'data-opts': JSON.stringify(attr) })
245 );
246 }
247 });
248 }() );
249